Blezz
Blezz

Reputation: 323

Haskell multiple bindings inside lambda

I am new to Haskell.

I have this code (my solution to one of the exercise from Ninety-Nine Haskell Problems)

data Structure a = Single a | Multiple (a, Int) deriving (Show) 

encodeM ::(Eq a)=> [a]->[Structure a]

encodeM l = map(\x -> (let size = length x
            --h = head x
            in if size>1 then Multiple ( head x, size) else Single (head x)
            )
          ) $ group l

When I uncomment "-h = head x" I get: "parse error on input `='"

But

xxx l= let size = length l  
   h = head l
      in  size

works fine, why it doesn't compile when I use "let" with multiple statement inside the lambda?

I have tried to replace let by where

encodeM2 ::(Eq a)=> [a]->[Structure a]

encodeM2 l = map(\x->if si>1 then Multiple ( head x, si) else Single (head x)
   where si = length x)

but it doesn't compile as well, whats wrong with it?

Upvotes: 3

Views: 2235

Answers (3)

kqr
kqr

Reputation: 15028

This is your code properly indented: (note how the let bindings align vertically)

encodeM :: Eq a => [a] -> [Structure a]
encodeM l = map (\x -> let size = length x
                           h = head x in
                       if size > 1
                          then Multiple (h, size)
                          else Single h) $
              group l

This is your code readable:

encodeM :: Eq a => [a] -> [Structure a]
encodeM = map runLength . group
  where
    runLength x =
      let size = length x
          h = head x in
      if size > 1
         then Multiple (h, size)
         else Single h

This is your code idiomatic:

encodeM :: Eq a => [a] -> [Structure a]
encodeM = map runLength . group
  where
    runLength [x] = Single x
    runLength xs = Multiple (head xs, length xs)

Upvotes: 12

Ankur
Ankur

Reputation: 33657

I prefer to use pattern matching to if/then/else, so your code becomes:

encodeM :: (Eq a) => [a] -> [Structure a]
encodeM lst = map fun $ group lst
              where
                fun [x] = Single x
                fun l = Multiple (head l, length l)

Upvotes: 4

kirelagin
kirelagin

Reputation: 13616

In Haskell whitespace matters.

Align assignemnts in your let. And you can't use where in lambda.

Upvotes: 2

Related Questions