Haskell,创建给定特定类型的函数
Haskell, Create a function given a specific type
我看了很多类似的话题,还是不明白。
所以问题是创建一个具有特定类型的函数
例如给定类型 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
,a
的类型为 a
.
:t \f g a -> f (g a)
我真的不明白这些步骤只是因为有 b->c
、a->b
和 a
类型的输入。然后我就猜到了顺序。
对于 1. 只有一个输入,所以它应该是 \f-> \g->...
。
(b -> c) -> (a -> b) -> a -> c
表示一个函数,有3个多态参数,前2个参数也是函数,第一个是b -> c
(接受b返回c的函数),第二个是a -> b
(函数接受 a 并返回 b)(参见 higher order functions)。 Lambda \f g a -> f (g a)
有三个参数,通过调用 g
的结果实现,参数 a
传递给 f
.
在实践中解决这些练习的最佳方法之一是使用 holes:写 _
来填充一个洞,然后从 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
。您只能使用该类型编写 non-terminating(或崩溃)程序。
我看了很多类似的话题,还是不明白。
所以问题是创建一个具有特定类型的函数
例如给定类型 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
,a
的类型为 a
.
:t \f g a -> f (g a)
我真的不明白这些步骤只是因为有 b->c
、a->b
和 a
类型的输入。然后我就猜到了顺序。
对于 1. 只有一个输入,所以它应该是 \f-> \g->...
。
(b -> c) -> (a -> b) -> a -> c
表示一个函数,有3个多态参数,前2个参数也是函数,第一个是b -> c
(接受b返回c的函数),第二个是a -> b
(函数接受 a 并返回 b)(参见 higher order functions)。 Lambda \f g a -> f (g a)
有三个参数,通过调用 g
的结果实现,参数 a
传递给 f
.
在实践中解决这些练习的最佳方法之一是使用 holes:写 _
来填充一个洞,然后从 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
。您只能使用该类型编写 non-terminating(或崩溃)程序。