【问题标题】:Haskell vs. erlang: difference in foldl?Haskell vs. erlang:foldl 的区别?
【发布时间】:2015-12-12 21:58:43
【问题描述】:

我注意到在 foldl 方面,Haskell 和 Erlang 之间存在差异。

对于foldr,两种语言返回相同的结果:

foldr (\x y -> 2*x+y) 4 [1, 2, 3] -- returns 49
lists:foldr(fun(X, Y) −> X+2∗Y end, 4, [1,2,3]). % returns 49

foldl 的返回值不同:

foldl (\x y -> x+2*y) 4 [1, 2, 3] -- returns 16
lists:foldl(fun(X, Y) −> X+2∗Y end, 4, [1,2,3]). -- returns 43

如何解释这种差异?

【问题讨论】:

  • foldlfoldr 的第一个参数的参数顺序在 Haskell 中似乎不同:foldl :: Foldable t => (b -> a -> b) -> b -> t a -> bfoldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
  • 2*x+y vs X+2*Y -- 这是故意的吗?
  • @chi 很细心,原来我把这两个混在一起了!但是,问题仍然存在,只是现在完全不同了……foldr 的行为相同,但foldl 返回的数字不同。
  • 支持 Dogbert 的建议:Erlang foldl(f,x,l) 似乎等同于 Haskell foldl (flip f) x l -- f 以不同的顺序接受参数。

标签: haskell erlang fold


【解决方案1】:

你没有简化你的折叠功能,这让你自己感到困惑。

向左折叠,Haskell

Prelude Debug.Trace> foldl (\x y -> trace("x:"++show x++" y:"++show y) $ x+y) 4 [1,2,3]
x:4 y:1
x:5 y:2
x:7 y:3
10

向左折叠,Erlang

1> lists:foldl(fun (X,Y) -> io:format("x:~p y:~p~n", [X,Y]), X+Y end, 4, [1,2,3]).
x:1 y:4
x:2 y:5
x:3 y:7
10

向右折叠,Haskell

Prelude Debug.Trace> foldr (\x y -> trace("x:"++show x++" y:"++show y) $ x+y) 4 [1,2,3]
x:3 y:4
x:2 y:7
x:1 y:9
10

向右折叠,Erlang

2> lists:foldr(fun (X,Y) -> io:format("x:~p y:~p~n", [X,Y]), X+Y end, 4, [1,2,3]).
x:3 y:4
x:2 y:7
x:1 y:9
10

由此可见,在 Haskell 中,foldl 函数将传递给 (Accumulator, Element),而 foldr 函数将传递给 (Element, Accumulator)。另一方面,Erlang 中的两个函数都将传递(Element, Accumulator)

【讨论】:

    猜你喜欢
    • 2010-12-21
    • 2016-05-16
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2014-06-14
    • 1970-01-01
    相关资源
    最近更新 更多