Defining foldl in terms of foldr

后端 未结 2 1021
北荒
北荒 2021-01-20 03:24
myFoldl :: (a -> b -> a) -> a -> [b] -> a

myFoldl f z xs = foldr step id xs z
    where step x g a = g (f a x)

I am currently readi

2条回答
  •  猫巷女王i
    2021-01-20 04:17

    As Adam Smith says in the comments, there are only three arguments to foldr. The line in question gets parsed like this:

    myFoldl f z xs = (foldr step id xs) z
    

    There are other implicit brackets too of course, but these are the important ones.

    Here is a rewrite with the type annotations, assuming scoped type variables (i.e. a and b mean the same types throughout this definition).

    myFoldl :: (a -> b -> a) -> a -> [b] -> a
    myFoldl f z xs =  goFold z
       where
          goFold :: a -> a
          goFold = foldr step id xs
          step :: b -> (a -> a) -> (a -> a)  -- Last brackets are redundant
          step x g a = g (f a x)
    

    I've moved the foldr invocation into a separate value goFold so you can see its type and how it gets applied to the z value. The step function accumulates the b values into a function of type (a -> a). Each b value processed by goFold adds an extra one of these. The "zero" for functions is of course id from the Prelude:

    id :: a -> a
    id x = x
    

    The -> function operator in the types is right associative, so the last pair of brackets in the step type are redundant. But I've written it like that because it higlights the way in which step is being used; it takes a value and a function and returns a new function.

提交回复
热议问题