点在哈斯克尔,一个棘手的例子

时间:2016-08-28 19:37:10

标签: haskell

我知道" haskells dot"问题在stackoverflow之前被回答了几次,但我遇到了一个例子,它向我展示了我还没有完全得到它。我们说我有功能

f :: Integer -> Integer
f x = x
g x = \y -> y

现在,据我所知,dot的作用类似于函数组合 - > f (g x) = (f . g) x 。所以

(f . g) 4 5

shuld返回5.因为g接受两个参数并返回第二个参数,而f只是身份。然而,它没有,我得到Couldn't match type错误。我有一种感觉,即haskell将这种表达解析为((f . g) 4) 5之类的东西。但我需要更深入的解释

2 个答案:

答案 0 :(得分:2)

正如问题所述,我们有:

(f . g) x = f (g x)

因此,特别是

(f . g) 4 = f (g 4)               (*)

我们有

(f . g) 4 5
=   -- application associates to the left
((f . g) 4) 5
=   -- equation (*) above
(f (g 4)) 5 =
=   -- application associates to the left
f (g 4) 5

我们现在可以看到最后一个参数5被保留为f的第二个参数,而不是传递给g

记住Haskell函数是有用的是很有用的:从技术上讲,没有一个函数需要两个参数。具有类型a -> b -> c的函数实际上是返回一元函数的一元函数,即使我们想将其视为二元函数。

组合运算符也适用于一元函数:f . g组成一元函数fg。如果f是“二进制”,则将其视为返回函数的一元函数。这使得它需要一个额外的参数,如上所示。如果g是“二进制”,则其返回的函数将传递给f

所以,使用上面的定义:

f x = x
g x = \y -> y

我们得到:

(f . g) 4 5
= -- done above
f (g 4) 5
= -- associativity
(f (g 4)) 5
= -- definition of f
(g 4) 5
= -- definition of g
(\y -> y) 5
= -- beta reduction
5

答案 1 :(得分:0)

main = print $(f . g) 4 5

f x = x
g x = \y -> y

很好地编译并在运行时打印5.我正在使用GHC 8.0.1。 也许你宁愿提供一个完整的最小等例子?