我已经为问题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)
我想重写相同的解决方案,但这次使用let语法。
{-- 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
第二个例子不起作用。错误是:
*Main> :l Problem10.hs
Compiling Main ( Problem10.hs, interpreted )
Problem10.hs:16:38: parse error on input `='
Failed, modules loaded: none.
第16行是这一行:rem = dropWhile (==x) (x:xs)
有什么建议吗?
LE:是的,这是一个缩进问题。似乎我的编辑器(Notepad ++)应该稍微配置一下以避免这样的问题。答案 0 :(得分:7)
如前所述,这是一个缩进问题,它是由以rem
开头的行缩小而不是前一行所引起的,因此它不会被解析为属于先前的let
语句。确定如何在Haskell中缩进的一种好方法是来自offside rule的Real World Haskell。
使用let
语句启动函数时,通常最好放到新行,以避免大缩进,如下所示:
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
答案 1 :(得分:4)
正如@templatetypedef指出的那样, 确实是缩进。 rem =
需要与num =
对齐。