hi ::(b - > c) - > (a - > b) - > (a - > c)在Haskell中

时间:2014-03-17 08:43:17

标签: haskell functional-programming

我在Haskell中有以下类型签名:

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

我想写一个具体的实现,但我真的很难理解从哪里开始。我知道hi需要一个函数(b - > c),它返回一个函数(a - > b),它最终返回一个函数(a - > c)。

有人能告诉我一个具体实现的例子吗?我如何知道从哪里开始这样的事情以及定义左侧的内容?

2 个答案:

答案 0 :(得分:26)

考虑到这一点的一种方法是使用(b -> c)(a -> b)并返回另一个函数(a -> c)的函数。那么让我们从

开始吧
hi f g = undefined       -- f :: b -> c, g :: a -> b

我们知道返回类型必须是函数(a -> c) -

hi f g = \a -> undefined -- f :: b -> c, g :: a -> b

我们现在右侧有a类型的东西,我们有一个函数g :: a -> b所以一个明智的事情(事实上,我们唯一可以做的)是申请ga

hi f g = \a -> g a       -- ok, this fails to typecheck...

表达式g a的类型为bf :: b -> c,我们希望最终得到c。所以,我们只能做一件事 -

hi f g = \a -> f (g a)

这种类型检查!我们现在开始清理过程。我们可以将a移动到等号的左侧

hi f g a = f (g a)

而且,如果您碰巧知道合成运算符.,您可能会注意到它可以在这里使用

hi f g a = (f . g) a

现在a双方都是多余的(这称为eta reduction

hi f g = f . g

我们可以使用函数形式.

(.)运算符拉到表达式的前面
hi f g = (.) f g

现在gf都是多余的(另外两个eta减少应用)

hi = (.)

所以你的函数hi只不过是函数组合。

答案 1 :(得分:3)

你读错了:->运算符是右关联的。因此,您的签名是:(b->c) -> ((a->b) -> (a->c))。所以你可以把它读作:给定一个从bc的函数,它返回一个函数,它从ab取一个函数,最后从{返回一个函数{1}}至a

从那里,你应该能够自己解决这个问题。