简体   繁体   中英

Issues with foldl in ghci

Trying this in ghci:

foldl (:) [1] [2,3,4]

which gives the following error:

<interactive>:51:7: error:
    • Couldn't match type ‘a’ with ‘[a]’
      Expected: [a] -> [[a]] -> [a]
        Actual: [a] -> [[a]] -> [[a]]
      ‘a’ is a rigid type variable bound by
        the inferred type of it :: [a]
        at <interactive>:51:1-21
    • In the first argument of ‘foldl’, namely ‘(:)’
      In the expression: foldl (:) [1] [2, 3, 4]
      In an equation for ‘it’: it = foldl (:) [1] [2, 3, 4]
    • Relevant bindings include it :: [a] (bound at <interactive>:51:1)

But the same thing works with foldr

foldr (:) [1] [2,3,4]

which outputs [2,3,4,1]

Shouldn't the foldl output (above) be [1,2,3,4]? As per my understanding, the only difference between foldl and foldr is where the accumulator is placed so I am not understanding this error.

The signatures of foldl and foldr` differ. Indeed:

foldl :: Foldable f => (b -> a -> b) -> b -> t a -> b
foldr :: Foldable f => (a -> b -> b) -> b -> t a -> b

Notice the different order of a and b in the "fold function" (first parameter).

This is likely to stress that foldl z [x 1 , x 2 , …, x n ] is defined as: z [x 1 , x 2 , …, x n ]被定义为:

foldl  z [x1, x2, …, xn] =  (… ( ( z x1) x2) …) xn

whereas for foldr z [x 1 , x 2 , …, x n ] , we get: z [x 1 , x 2 , …, x n ] ,我们得到:

foldr  z [x1, x2, …, xn] =  x1 ( x2 (… ( xn z) …))

You thus can work with:

foldl (flip (:)) [1] [2,3,4]

But this will not give the same result, since we construct:

foldl (flip (:)) [1] [2,3,4] = 4 : (3 : (2 : [1]))
                             = [4, 3, 2, 1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM