我很难理解类型声明是如何工作的......例如:t::(a -〉B)-〉(b -〉c)-〉a -〉cs::(a -〉B -〉c)-〉(a -〉b)-〉a -〉c通过尝试不同的方法,我知道正确的函数应该是这样的:第一个但这是如何工作的呢?为什么括号在最后?为什么不是
t f g x = (f x) g
或
s f g x = (f x) g x
我迷失了
zkure5ic1#
对于第一个示例:
t :: (a -> b) -> (b -> c) -> a -> c
在类型声明中,type1 -> type2模式指示从type1到type2的函数。在类型声明中,->运算符是右关联的,因此它被分析为:
type1 -> type2
type1
type2
->
t :: (a -> b) -> ((b -> c) -> (a -> c))
这种施工叫做“赶时髦”:提供第一参数(类型a -> b)产生接受第二参数(类型b -> c)的函数,第二参数(类型b -> c)产生接受第三参数(类型a)的函数。函数声明的语法是自动设置的,前两个参数是函数,第三个参数是a,所以从反映这一点的名称开始:f :: a -> b和g :: b -> c是函数,而x :: a是完全泛型类型,可以是任何类型。
a -> b
b -> c
a
f :: a -> b
g :: b -> c
x :: a
t f g x = ...
请注意,Haskell中的函数应用只是连接:要将函数f应用于值x,只需使用f x。此语法是 left-associative,因此t f g x被解析为(((t f) g) x),以匹配上述currying结构。无论如何,给定这些类型,在如何将它们组合在一起方面,您没有太多选择:
f
x
f x
t f g x
(((t f) g) x)
b
g
g (f x)
c
t
不能执行(f x) g的原因是类型不匹配:
(f x) g
f :: a -> b x :: a (f x) :: b g :: b -> c
所以,你可以把g :: b -> c应用到(f x) :: b上,得到c类型的结果,但反过来就不行了,因为b可能根本不是函数类型。
(f x) :: b
1条答案
按热度按时间zkure5ic1#
对于第一个示例:
在类型声明中,
type1 -> type2
模式指示从type1
到type2
的函数。在类型声明中,->
运算符是右关联的,因此它被分析为:这种施工叫做“赶时髦”:提供第一参数(类型
a -> b
)产生接受第二参数(类型b -> c
)的函数,第二参数(类型b -> c
)产生接受第三参数(类型a
)的函数。函数声明的语法是自动设置的,前两个参数是函数,第三个参数是
a
,所以从反映这一点的名称开始:f :: a -> b
和g :: b -> c
是函数,而x :: a
是完全泛型类型,可以是任何类型。请注意,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
的原因是类型不匹配:所以,你可以把
g :: b -> c
应用到(f x) :: b
上,得到c
类型的结果,但反过来就不行了,因为b
可能根本不是函数类型。