1

I have a lambda function ((:) . ((:) x)) that I am passing to foldr like so: foldr ((:) . ((:) x)) [] xs where xs is a 2d list. I would like to refactor to make it clearer (so I can better understand it). I imagine it would be done like so:

foldr (\ element acc -> (element:acc) . (x:acc)) [] xs

But this gives me the error:

ex.hs:20:84: error:
    • Couldn't match expected type ‘a0 -> b0’ with actual type ‘[[a]]’
    • Possible cause: ‘(:)’ is applied to too many arguments
      In the second argument of ‘(.)’, namely ‘(x : acc)’
      In the expression: (element : acc) . (x : acc)
      In the first argument of ‘foldr’, namely
        ‘(\ element acc -> (element : acc) . (x : acc))’
    • Relevant bindings include
        acc :: [[a]] (bound at ex.hs:20:60)
        element :: [a] (bound at ex.hs:20:52)
        xs :: [[a]] (bound at ex.hs:20:30)
        x :: [a] (bound at ex.hs:20:28)
        prefixes :: [a] -> [[a]] (bound at ex.hs:20:1)
   |
20 | prefixes = foldr (\x xs -> [x] : (foldr (\ element acc -> (element:acc) . (x:acc)) [] xs)) []
   |  

Edit: My all relevant code surrounding this snippet is

prefixes :: Num a => [a] -> [[a]]
prefixes = foldr (\x acc -> [x] : (foldr ((:) . ((:) x)) [] acc)) []

and its invocation is:

prefixes [1, 2, 3]

How can I refactor the lambda ((:) . ((:) x)) to include both its arguments?

1
  • 2
    For what it's worth, that's a function expression but it's not a lambda. Lambdas are a very specific construct - they provide syntax for creating anonymous functions with named arguments. But Haskell treats functions as regular values, providing ways to pass them around and modify them without ever using a lambda construct. That's what the code in your initial example does. Commented Mar 17, 2022 at 19:09

1 Answer 1

8

You can step-by-step convert it to a lambda.

(:) . ((:) x)
\y -> ((:) . (((:) x)) y  -- conversion to lambda
\y -> (:) (((:) x) y)     -- definition of (.)
\y -> (:) (x : y)         -- rewrite second (:) using infix notation
\y z -> (:) (x : y) z     -- add another parameter
\y z -> (x : y) : z       -- rewrite first (:) using infix notation
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.