让Haskell中的语法

And*_*anu 3 haskell indentation

在Haskell中为问题10 (99个问题)编写了以下解决方案:

{-- using dropWhile and takeWhile --}
enc :: (Eq a) => [a] -> [(Int, a)]
enc [] = []
enc (x:xs) = (length $ takeWhile (==x) (x:xs), x) : enc (dropWhile (==x) xs)
Run Code Online (Sandbox Code Playgroud)

我想重写相同的解决方案,但这次使用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
Run Code Online (Sandbox Code Playgroud)

第二个例子不起作用.错误是:

*Main> :l Problem10.hs
Compiling Main             ( Problem10.hs, interpreted )

Problem10.hs:16:38: parse error on input `='
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

第16行是这一行: rem = dropWhile (==x) (x:xs)

有什么建议 ?

LE:是的,这是一个缩进问题.似乎我的编辑器(Notepad ++)应该稍微配置一下以避免这样的问题.

Has*_*ant 7

前面已经提到,这是一个压痕问题,它的第一步是用线造成的 rem是少缩进然后前行,因此不会被解析为属于以前的let声明.确定如何在Haskell中缩进的好方法是来自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
Run Code Online (Sandbox Code Playgroud)