首页 > 解决方案 > 从签名实现 Haskell 函数

问题描述

我试图围绕 Haskell 进行思考,但在尝试将以下签名实现为函数时遇到了麻烦。你们能给我一个使用 lambda 表达式的例子吗?

(b -> c) -> (a -> b) -> a -> c

标签: haskell

解决方案


首先尝试使用更简单的示例。例如,

f :: a -> a
f = ...

由于f是一个参数的函数,我们可以扩展它而无需过多考虑:

f :: a -> a
f = \x -> ...

为这个函数选择一个返回值,我们正好有一个好的候选者,x,所以:

f :: a -> a
f = \x -> x

虽然我们也可以选择undefinedor error "meh", or f x,它们不太有用。


这是另一个简单的例子:

g :: (a, b) -> (b, a)
g = ...

唯一匹配函数输入的模式是一对,所以:

g :: (a, b) -> (b, a)
g = \(x, y) -> ...

不必等价于swap,但它是一个很好的候选,因为它终止。


最后一个更复杂的例子:

h :: ((a, b) -> c) -> a -> b -> c
h = ...

这是三个类型参数的函数(a, b) -> cab所以不用多想,我们可以部分扩展答案:

h :: ((a, b) -> c) -> a -> b -> c
h = \f -> \x -> \y -> ...
h = \f x y -> ...

(下一行只是堆叠咖喱参数的一种方便方法。)

现在,我给了它们 names f,因为我认为它是一个好的通用名称,它包含一个,并且是任意值的好通用名称。我也可以选择并加强同名类型之间的联系,但这也会有点混乱。所以在这里,和。xyf->xyabx :: ay :: b

至于填写函数体,我可以问“如何应用我拥有的东西以使类型对齐”,或者我可以查看返回类型,c然后查看我可以制作的内容类型的值c。如果我给它喂一对 type ,则f返回。我有一个和一个,所以:c(a, b)x :: ay :: b(x, y) :: (a, b)

h :: ((a, b) -> c) -> a -> b -> c
h = \f x y -> f (x, y)

这是顺带的curry。我认为您找不到任何其他终止的解决方案?

对于简单的函数,通常只有一个好的候选者。当您的类型签名具有多个相同类型的值时,您必须考虑如果您选择一个而不是另一个会发生什么。我能想到的第一种情况是当你>>=为状态单子实现运算符时。


推荐阅读