我读了很多类似的主题,但仍然不明白。
所以问题是创建一个具有特定类型的函数
例如,给定类型 Integer-> Integer
,具有该类型的函数为 \x-> x+1
。如何查找以下类型的 lambda 函数:
(((Int → a) → a) → b) → b
(a -> b) -> c
a → (a → a)
(b -> c) -> (a -> b) -> a -> c
我通过猜测解决了4.:
\f g a -> f (g a)
lambda 后面的三个变量,f
的类型为 b->c
,g
的类型为 a->b
code>,并且 a
的类型为 a
。
:t\f g a -> f (g a)
我并没有真正理解这些步骤,只是有类型为 b->c
、a->b
和 a
的输入。然后我就猜到了顺序。
对于 1. 只有一个输入,因此应该是 \f->\g->...
。
最佳答案
在实践中解决这些练习的最佳方法之一是使用洞:编写_
来填充一个洞,并从GHCi中读取该洞的类型洞
> foo :: (((Int -> a) -> a) -> b) -> b ; foo = _
* Found hole: _ :: (((Int -> a) -> a) -> b) -> b
这个洞是一个函数。那么我们就使用 lambda 吧。
> foo :: (((Int -> a) -> a) -> b) -> b ; foo = \f -> _
* Found hole: _ :: b
* Relevant bindings include
f :: ((Int -> a) -> a) -> b
孔的类型必须为b
。不再有 lambda。我们无法创建 b
类型的值,除非我们以某种方式应用 f
(注意 f
的打印类型)。
> foo :: (((Int -> a) -> a) -> b) -> b ; foo = \f -> f _
* Found hole: _ :: (Int -> a) -> a
啊,现在这个洞又是一个函数了。另一个 lambda。
> foo :: (((Int -> a) -> a) -> b) -> b ; foo = \f -> f (\g -> _)
* Found hole: _ :: a
* Relevant bindings include
g :: Int -> a
好吧,现在我们需要生成a
。有了 g::Int -> a
供我们使用,这看起来很容易。
> foo :: (((Int -> a) -> a) -> b) -> b ; foo = \f -> f (\g -> g 42)
不再有漏洞——完成。
请注意,您的 2) (a -> b) -> c
不可能正确实现 - 无法从该输入生成 c
。您只能编写该类型的非终止(或崩溃)程序。
关于Haskell,创建一个给定特定类型的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72276491/