haskell 我不懂类型声明

vyswwuz2  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(142)

我很难理解类型声明是如何工作的......例如:
t::(a -〉B)-〉(b -〉c)-〉a -〉c
s::(a -〉B -〉c)-〉(a -〉b)-〉a -〉c
通过尝试不同的方法,我知道正确的函数应该是这样的:
第一个
但这是如何工作的呢?为什么括号在最后?为什么不是

t f g x = (f x) g

s f g x = (f x) g x

我迷失了

zkure5ic

zkure5ic1#

对于第一个示例:

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

在类型声明中,type1 -> type2模式指示从type1type2的函数。在类型声明中,->运算符是右关联的,因此它被分析为:

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

这种施工叫做“赶时髦”:提供第一参数(类型a -> b)产生接受第二参数(类型b -> c)的函数,第二参数(类型b -> c)产生接受第三参数(类型a)的函数。
函数声明的语法是自动设置的,前两个参数是函数,第三个参数是a,所以从反映这一点的名称开始:f :: a -> bg :: b -> c是函数,而x :: a是完全泛型类型,可以是任何类型。

t f g x = ...

请注意,Haskell中的函数应用只是连接:要将函数f应用于值x,只需使用f x。此语法是 left-associative,因此t f g x被解析为(((t f) g) x),以匹配上述currying结构。
无论如何,给定这些类型,在如何将它们组合在一起方面,您没有太多选择:

  • 关于类型a,你只知道它的类型是x,参数的类型是f,所以你能做的就是把函数应用到值上:f x .
  • 关于类型b,您所知道的唯一一件事就是它是f的结果类型和g的参数类型,因此您唯一能做的就是应用g (f x)
  • 关于类型c,您所知道的唯一一件事就是它是g的结果类型,也是整个函数t的结果类型,因此t只能返回g (f x)

不能执行(f x) g的原因是类型不匹配:

f :: a -> b
x :: a
(f x) :: b

g :: b -> c

所以,你可以把g :: b -> c应用到(f x) :: b上,得到c类型的结果,但反过来就不行了,因为b可能根本不是函数类型。

相关问题