正确实现foldl1

时间:2016-11-30 17:36:56

标签: haskell fold higher-order-functions

Haskell Wikibook提供了一个

foldl1           :: (a -> a -> a) -> [a] -> a
foldl1 f (x:xs)  =  foldl f x xs
foldl1 _ []      =  error "Prelude.foldl1: empty list"

不起作用。我试着编译它的这个版本:

myFoldl1           :: (a -> a -> a) -> [a] -> a
mFoldl1 f (x:xs)  =  myFoldl1 f x xs
myFoldl1 _ []      =  error "Prelude.foldl1: empty list

我首先认为它缺少一个结束折叠的案例,并且打字存在问题

foldl1 _ [x] = x
foldl1 f (x:xs)  =  foldl (f x) xs

但这也不会奏效。我认为类型问题更深入,但我没有足够的把握Haskell进一步思考。有人可以帮我吗?

3 个答案:

答案 0 :(得分:5)

mFoldl1 f (x:xs)  =  myFoldl1 f x xs

重命名函数时,您犯了两个错误:首先,您在上述案例的定义中错误拼写了函数名称(mFoldl1而不是myFoldl1),其次您将调用替换为原件foldl,递归调用myFoldl1

正确的版本是:

myFoldl1 f (x:xs) = foldl f x xs

答案 1 :(得分:1)

我也偶然发现了wikibook中的错误,并找到了这个条目。

上面的答案似乎是错误的:它们甚至不是正确的类型。

foldl1 f [x]       = x
fold11 f [x,y]     = f x y
foldl1 f x:y:zs    = f (f x y) (foldl1 f zs)
foldl1 _ []        = error "foldl1 undefined on []"
我认为,

完成这项工作。我希望有更优雅的东西。

答案 2 :(得分:0)

校正!以上作品,但原来使用foldl调用要好得多。 使用不能清楚区分“l”和“1”的字体会产生混淆!要清楚

fold1 f (x:xs) = foldl f x xs

是一个明显而简单的原创。