类型(c→d)→(a→b→c)→(a→b→d)的Haskell函数组合算子 [英] Haskell function composition operator of type (c→d) → (a→b→c) → (a→b→d)

查看:130
本文介绍了类型(c→d)→(a→b→c)→(a→b→d)的Haskell函数组合算子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

普通函数组合的类型是

 (。)::(b  - > c) - > (a  - > b) - > a  - > c 

我想这应该概括为类型:

 (。)::(c  - > d) - > (a→b→c)→> a  - > b  - > d 

一个具体的例子:计算差异平方。我们可以编写 diffsq ab =(a - b)^ 2 ,但感觉就像我应该可以编写( - )(^ 2)来编写类似于 diffsq =(^ 2)的内容。 ( - )



当然,我不能。我可以做的一件事就是使用一个元组而不是两个参数( - ),用 uncurry ,但这是不一样的。



有可能做我想做的事吗?如果不是,我误解的是什么让我觉得它应该是可能的?






注意:这实际上已经被问到这里,但答案(我怀疑必须存在)没有给出。

解决方案

误解是您认为 a - > ; b - > c 作为返回类型 c 的两个参数的函数,而它实际上是一个参数的函数,返回类型为 b - > c ,因为函数类型与右边相关联(即它与 a - >(b - > c)相同),这使得它不可能使用标准函数组合运算符。



为了弄明白为什么,试着应用(。)运算符,它是将(y - > z) - >(x - > y) - >(x - > z)运算符类型化为两个函数< $ c> g :: c - > d f :: a - >(b - > c)我们必须将 y c 以及 b - > c 。这没什么意义, y 既可以是 c ,也可以是返回 c ?那将是一个无限的类型。所以这是行不通的。



仅仅因为我们不能使用标准组合运算符,它不会阻止我们定义自己的。

  compose2 ::(c  - > d) - > a  - > b  - > c) - > a  - > b  - > d 
compose2 gfxy = g(fxy)

diffsq =(^ 2)`compose2`( - )

通常最好避免使用point-在这种情况下免费的风格,只需与

  diffsq ab =(ab)^ 2 


Ordinary function composition is of the type

(.) :: (b -> c) -> (a -> b) -> a -> c

I figure this should generalize to types like:

(.) :: (c -> d) -> (a -> b -> c) -> a -> b -> d

A concrete example: calculating difference-squared. We could write diffsq a b = (a - b) ^ 2, but it feels like I should be able to compose the (-) and (^2) to write something like diffsq = (^2) . (-).

I can't, of course. One thing I can do is use a tuple instead of two arguments to (-), by transforming it with uncurry, but this isn't the same.

Is it possible to do what I want? If not, what am I misunderstanding that makes me think it should be possible?


Note: This has effectively already been asked here, but the answer (that I suspect must exist) was not given.

解决方案

The misunderstanding is that you think of a function of type a -> b -> c as a function of two arguments with return type c, whereas it is in fact a function of one argument with return type b -> c because the function type associates to the right (i.e. it's the same as a -> (b -> c). This makes it impossible to use the standard function composition operator.

To see why, try applying the (.) operator which is of type (y -> z) -> (x -> y) -> (x -> z) operator to two functions, g :: c -> d and f :: a -> (b -> c). This means that we must unify y with c and also with b -> c. This doesn't make much sense. How can y be both c and a function returning c? That would have to be an infinite type. So this does not work.

Just because we can't use the standard composition operator, it doesn't stop us from defining our own.

 compose2 :: (c -> d) -> (a -> b -> c) -> a -> b -> d
 compose2 g f x y = g (f x y)

 diffsq = (^2) `compose2` (-)

Usually it is better to avoid using point-free style in this case and just go with

 diffsq a b = (a-b)^2

这篇关于类型(c→d)→(a→b→c)→(a→b→d)的Haskell函数组合算子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆