为什么Haskell中的函数组合是正确的关联? [英] Why is function composition in Haskell right associative?

查看:124
本文介绍了为什么Haskell中的函数组合是正确的关联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在数学上,函数组合操作是关联的。因此:

  f。 (g。h)=(f。g)。 h 

因此,函数组合操作可以定义为左结合或右结合。



由于Haskell中的正常函数应用(即并列项,而不是 $ 操作)在我的观点函数中保持关联组成也应该保持联想。毕竟,世界上大多数人(包括我自己)都习惯从左到右阅读。



然而,Haskell中的函数组合是正确的关联:

  infixr 9。 

我知道,函数组合操作是关联的还是正确的关联。不过,我很想知道为什么它不是联想。我对这个设计决策有两个理由:


  1. Haskell的制作者希望函数组合在逻辑上与<$ c
  2. Haskell的制造者之一是日本人,他发现让函数组合更直观,而不是左联合。 / li>

抛开笑话,是否有任何有利的原因让函数组合在Haskell中正确关联?如果Haskell中的函数组合是关联的,它会有什么区别吗?

解决方案

在存在非严格评估的情况下,结合性是有用的。让我们来看一个非常愚蠢的例子:

  foo :: Int  - > Int 
foo = const 5。 (+3)。 (`div` 10)

好的,当 infixr

  foo 0 
=> (const 5。((+3)。(`div` 10)))0
=> ((\ x - > const 5(((+3)。(`div` 10))x))0
=> const 5(((+3)。(`div` 10))0)
=> 5

现在,如果 infixl

  foo 0 
=> ((const 5。(+3))。(`div` 10))0
=> (\ x - >(const 5.(+3))(x`div` 10))0
=> (const 5.(+3))(0`div` 10)
=> (\ x - > const 5(x + 3))(0`div` 10)
=> const 5((0` div` 10)+ 3)
=> 5

(我有点累,如果我在这些缩减步骤中犯了错误, >请让我知道,或者只是修复它们。)



他们有相同的结果,是的。但减少步骤的数量并不相同。当为左关联时,合成操作可能需要减少更多次 - 特别是,如果链中较早的函数决定使其不需要嵌套计算的结果。最糟糕的情况是一样的,但在最好的情况下,右结合可能是一个胜利。所以,选择有时更好的选择,而不是有时更糟的选择。


Mathematically the function composition operation is associative. Hence:

f . (g . h) = (f . g) . h

Thus the function composition operation may be defined to be either left associative or right associative.

Since normal function application in Haskell (i.e. the juxtaposition of terms, not the $ operation) is left associative in my opinion function composition should also be left associative. After all most people in the world (including myself) are used to reading from left to right.

Nevertheless function composition in Haskell is right associative:

infixr 9 .

I know that it doesn't really make a difference whether the function composition operation is left associative or right associative. Nevertheless I'm curious to know why is it not left associative. Two reasons come to my mind for this design decision:

  1. The makers of Haskell wanted function composition to be logically as similar as the $ operation.
  2. One of the makers of Haskell was a Japanese who found it more intuitive to make function composition right associative instead of left associative.

Jokes aside, is there any beneficial reason for function composition to be right associative in Haskell? Would it make any difference if function composition in Haskell was left associative?

解决方案

In the presence of non-strict evaluation, right-associativity is useful. Let's look at a very dumb example:

foo :: Int -> Int
foo = const 5 . (+3) . (`div` 10)

Ok, what happens when this function is evaluated at 0 when . is infixr?

foo 0
=> (const 5 . ((+3) . (`div` 10))) 0
=> (\x -> const 5 (((+3) . (`div` 10)) x)) 0
=> const 5 (((+3) . (`div` 10)) 0)
=> 5

Now, what if . was infixl?

foo 0
=> ((const 5 . (+3)) . (`div` 10)) 0
=> (\x -> (const 5 . (+3)) (x `div` 10)) 0
=> (const 5 . (+3)) (0 `div` 10)
=> (\x -> const 5 (x + 3)) (0 `div` 10)
=> const 5 ((0 `div` 10) + 3)
=> 5

(I'm sort of tired. If I made any mistakes in these reduction steps, please let me know, or just fix them up..)

They have the same result, yes. But the number of reduction steps is not the same. When . is left-associative, the composition operation may need to be reduced more times - in particular, if a function earlier in the chain decides to shortcut such that it doesn't need the result of the nested computation. The worst cases are the same, but in the best case, right-associativity can be a win. So go with the choice that is sometimes better, instead of the choice that is sometimes worse.

这篇关于为什么Haskell中的函数组合是正确的关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆