haskell - 从签名实现 Haskell 函数
问题描述
我试图围绕 Haskell 进行思考,但在尝试将以下签名实现为函数时遇到了麻烦。你们能给我一个使用 lambda 表达式的例子吗?
(b -> c) -> (a -> b) -> a -> c
解决方案
首先尝试使用更简单的示例。例如,
f :: a -> a
f = ...
由于f
是一个参数的函数,我们可以扩展它而无需过多考虑:
f :: a -> a
f = \x -> ...
为这个函数选择一个返回值,我们正好有一个好的候选者,x
,所以:
f :: a -> a
f = \x -> x
虽然我们也可以选择undefined
or 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) -> c
和a
,b
所以不用多想,我们可以部分扩展答案:
h :: ((a, b) -> c) -> a -> b -> c
h = \f -> \x -> \y -> ...
h = \f x y -> ...
(下一行只是堆叠咖喱参数的一种方便方法。)
现在,我给了它们 names f
,因为我认为它是一个好的通用名称,它包含一个,并且是任意值的好通用名称。我也可以选择并加强同名类型之间的联系,但这也会有点混乱。所以在这里,和。x
y
f
->
x
y
a
b
x :: a
y :: b
至于填写函数体,我可以问“如何应用我拥有的东西以使类型对齐”,或者我可以查看返回类型,c
然后查看我可以制作的内容类型的值c
。如果我给它喂一对 type ,则f
返回。我有一个和一个,所以:c
(a, b)
x :: a
y :: b
(x, y) :: (a, b)
h :: ((a, b) -> c) -> a -> b -> c
h = \f x y -> f (x, y)
这是顺带的curry
。我认为您找不到任何其他终止的解决方案?
对于简单的函数,通常只有一个好的候选者。当您的类型签名具有多个相同类型的值时,您必须考虑如果您选择一个而不是另一个会发生什么。我能想到的第一种情况是当你>>=
为状态单子实现运算符时。
推荐阅读
- reactjs - 无法将 CSS 模块导入 React TypeScript 项目 #121
- nsis - NSIS:如何删除/隐藏 MUI_LICENSEPAGE_TEXT_BOTTOM?
- c++ - 我在构造函数调用期间面临运算符重载问题
- node.js - 我收到此错误:类型 '(err: Error) => void' 与类型 'QueryOptions'.ts(2559) 没有共同的属性,我不知道是什么原因
- html - 带有href图像内的文本框的悬停效果
- c# - POST请求C#中的Localbitcoins API签名
- html - 为 DOM 样式光标属性使用图像 URL
- list - 如何从列表中删除相同的飞镖:颤振
- html - 在css水平条形图之前和之后放置文本
- mongodb - 如何查找具有最大字段值的文档并一次性(原子地)更新它?