Let syntax in Haskell
I have written the following solution for Problem 10 (99 questions) in Haskell :
{-- using dropWhile and takeWhile --}
enc :: (Eq a) => [a] -> [(Int, a)]
enc [] = []
enc (x:xs) = (length $ takeWhile (==x) (x:xs), x) : enc (dropWhile (==x) xs)
I wanted to rewrite the same solution but this time using a let syntax .
{-- using dropWhile and takeWhile / more readable --}
enc' :: (Eq a) => [a] -> [(Int, a)]
enc' [] = []
enc' (x:xs) = let num = length $ takeWhile (==x) (x:xs)
rem = dropWhile (==x) (x:xs)
in (num, x) : enc' rem
The second example is not working . The error is:
*Main> :l Problem10.hs
Compiling Main ( Problem10.hs, interpreted )
Problem10.hs:16:38: parse error on input `='开发者_JAVA百科
Failed, modules loaded: none.
Where line 16 is this one: rem = dropWhile (==x) (x:xs)
Any suggestions ?
LE: Yes, it was an indentation problem . It seems that my editor (Notepad++) should be configured a little to avoid problems like this .
As already mentioned this is an indentation problem, it's caused by the line starting with rem
being less indented then the previous line so it is not parsed as belonging to the previous let
statement. A good way of determining how to indent in Haskell is the offside rule from Real World Haskell.
Also it is often a good idea to drop to a new line when starting your function with a let
statement so to avoid wide indentation, like this:
enc :: (Eq a) => [a] -> [(Int, a)]
enc [] = []
enc (x:xs) =
let num = length . takeWhile (==x) $ x:xs
rem = dropWhile (==x) (x:xs)
in (num, x) : enc rem
As @templatetypedef points out, it is indeed the indentation. The rem =
needs to be aligned with the num =
.
精彩评论