让Haskell中的语法

时间:2011-01-11 09:30:18

标签: haskell indentation

我已经为问题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 ++)应该稍微配置一下以避免这样的问题。

2 个答案:

答案 0 :(得分:7)

如前所述,这是一个缩进问题,它是由以rem开头的行缩小而不是前一行所引起的,因此它不会被解析为属于先前的let语句。确定如何在Haskell中缩进的一种好方法是来自offside ruleReal 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 =对齐。