阅读http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html表明
特别要注意,功能箭头与右侧相关联 是,W - > X - > Y - > Z等于W - > (X - >(Y - > Z))。我们可以 始终在最右边的顶级箭头周围添加或删除括号 在一个类型。
函数箭头与右侧相关联,但是当函数应用程序与左侧相关联时,此信息的用处是什么?我觉得我不理解对我来说这是一个无意义的点,功能箭头与右边相关联。由于函数应用程序始终与左侧相关联,那么这是我应该关注的唯一关联性吗?
答案 0 :(得分:13)
功能箭头与右侧相关但[...]此信息的用处是什么?
如果您看到类型签名,例如f : String -> Int -> Bool
,您需要知道函数箭头的关联性,以了解f
的类型是什么:
(String -> Int) -> Bool
,即f
将函数作为参数并返回布尔值。String -> (Int -> Bool)
,即f
将字符串作为参数并返回一个函数。这是一个很大的区别,如果你想使用f
,你需要知道它是哪一个。由于函数箭头与右侧相关联,因此您知道它必须是第二个选项:f
接受一个字符串并返回一个函数。
与右侧[...]功能应用程序相关联的功能箭头与左侧
相关联
这两个选择很好地协同工作。例如,我们可以将上面的f
称为f "answer" 42
,这实际上意味着(f "answer") 42
。所以我们将字符串"answer"
传递给f
,返回一个函数。然后我们将数字42
传递给该函数,该函数返回一个布尔值。实际上,我们几乎使用f
作为具有两个参数的函数。
这是在Haskell中使用两个(或多个)参数编写函数的标准方法,因此它是一个非常常见的用例。由于函数应用程序和函数箭头的关联性,我们可以编写这个没有括号的常见用例。
答案 1 :(得分:5)
在定义双参数curried函数时,我们通常会写这样的东西:
f :: a -> b -> c
f x y = ...
如果箭头没有与右侧相关联,则上述类型必须拼写为a -> (b -> c)
。因此->
关联性的有用性在于它在声明函数类型时不会编写太多括号。
答案 2 :(得分:1)
如果运算符#
是'右关联',则表示:
a # b # c # d = a # (b # (c # d))
...对于任意数量的论点。它的行为类似于foldr
这意味着:
a -> b -> c -> d = a -> (b -> (c -> d))
注意:a -> (b -> (c -> d)) =/= ((a -> b) -> c) -> d
!这非常重要。
这告诉我们的是,foldr
:
λ> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
使用类型为(a -> b -> b)
的函数,然后返回...一个带b
的函数,然后返回...一个带[a]
的函数,然后返回... b
。这意味着我们可以应用这样的函数
f a b c
,因为
f a b c = ((f a) b) c
每次给出参数时,和f
将返回两个函数。
基本上,这不是非常有用的,但它是我们想要解释和调用函数类型的重要信息。
然而,在像(++)
这样的函数中,关联性很重要。如果(++)
是关联的,那么它会很慢,所以它是正确的关联。
答案 3 :(得分:0)
早期的函数式语言Lisp遭受过度嵌套的括号(这使得代码(甚至文本(如果你不介意考虑更广泛的上下文))难以阅读。随着时间的推移,功能语言设计者选择使功能代码易于阅读并且为专业人士写信,即使是以不太统一的规则来混淆新手的费用。
在功能代码中, 函数类型声明,如(String - > Int) - > Bool比String这样的函数更为罕见 - > (Int - > Bool),因为返回函数的函数是函数式的商标。因此,将箭头关联到右侧有助于减少括号数(在超出时,您可能需要将函数映射到基本类型)。对于功能应用程序,反之亦然。
答案 4 :(得分:0)
主要目的是方便,因为部分功能应用程序从左到右。
每次将函数部分应用到一组值时,其余类型必须有效。
您可以将箭头类型视为类型队列,其中队列本身就是类型。在部分函数应用程序中,您从队列中将与类型数量一样多的类型从队列中出队,从而产生队列中的剩余内容。结果队列仍然是有效类型。
这就是为什么类型关联到右侧。如果类型与左侧关联,它将表现得像一个堆栈,并且您将无法以同样的方式部分应用它,而不会留下“漏洞”或未定义的域。例如,假设您具有以下功能:
foo :: a -> b -> c -> d
如果Haskell类型是左关联的,则将单个参数传递给foo将产生以下无效类型:
((? -> b) -> c) -> d
然后您将被迫通过添加括号来绕开它,这可能会影响可读性。