Haskell:使用Let语句进行缩进

时间:2014-12-30 19:33:14

标签: haskell

我担心我会理解这一点和let一般情况。

以下代码:

splitWith tf xs 
    |(null xs) = [[]]
    |((length xs) == 1) = [xs]
    |otherwise = let tpl = (break tf xs) 
                     x = (fst tpl) 
                     xrst =  (snd tpl)
         in [[x] ,(splitWith tf (tail xrst))]

创建此语法错误:

  

[1/1]编译Main(ch04_exercise.hs,解释)
  ch04_exercise.hs:31:26:解析输入'x'

时的错误

这是在我删除了Sublime Text 2中的标签并将空格放入以排列变量之后发生的。在我这样做之前,我在x之后的=符号处得到了语法错误。

知道我做错了什么吗?

3 个答案:

答案 0 :(得分:4)

in必须与let对齐或位于同一行:

| otherwise = let (x, xrst) = break tf xs
              in [[x], splitWith tf (tail xrst)]

这就是为什么我通常更喜欢将let放在自己的行上:

| otherwise =
    let (x, xrst) = break tf xs
    in [[x], splitWith tf (tail xrst)]

你也有不必要的括号,可以从一些模式匹配中受益(如上所示)。

答案 1 :(得分:2)

编译器抱怨x = (fst tpl)因为它的左边缘没有与tpl =对齐。

你只删除了一些标签。我将标签设为<------>,空格设为.

splitWith tf xs 
<------><------>|(null xs) = [[]]
<------><------>|((length xs) == 1) = [xs]
<------><------>|otherwise = let tpl = (break tf xs) 
.........................x = (fst tpl) 
.........................xrst =  (snd tpl)
<------><------>.....in [[x] ,(splitWith tf (tail xrst))]

编译器使用8的倍数的tabstops。您认为tpl =的位置与编译器认为的位置之间的差异为8表明编辑器的tabstops为4的倍数,如下所示:

splitWith tf xs 
<--><-->|(null xs) = [[]]
<--><-->|((length xs) == 1) = [xs]
<--><-->|otherwise = let tpl = (break tf xs) 
.........................x = (fst tpl) 
.........................xrst =  (snd tpl)
<--><-->.....in [[x] ,(splitWith tf (tail xrst))]

这看起来很好而且正确,但不是编译器看到它的方式!

如果你坚持空间,这是最简单的。更改编辑器的设置。

如果你只使用没有任何标签的空格,你就不会遇到这个问题,因为你的编辑必须按照编译器的想法来展示它。

我的编辑器让我指定当我按Tab键时,它应该插入一个选项卡显示的空格数,所以我使用它,这对于一个4的tabstop是安全的。如果你的编辑器可以这样做,请使用那个选择。 (如果没有,请考虑在编程时获得一个更聪明的编辑器。)

我的编辑器也有自动缩进和outdent,其中下一行复制前一行的空白缩进 - 这避免了问题。如果您的编辑器支持它,请启用它,因为它可以节省您的工作量,并且您不太可能得到解析错误。 (当我按下退格键时,我的编辑器会删除回到上一级别的缩进,这很不错。)

几乎所有编辑都可以更改显示标签的方式。如果你不能使用空格作为标签,你应该将tabstop改为8,因为它与ghc相匹配,并且你不太可能得到这个错误,但你仍然是最好使用空格。

答案 2 :(得分:0)

编译此代码(虽然类型错误)

我认为这里学到的一般教训是,如果你在下一行开始它们,排队let分配会更容易。

splitWith tf xs 
    |(null xs) = [[]]
    |((length xs) == 1) = [xs]
    |otherwise = let 
                    tpl = (break tf xs) 
                    x = (fst tpl) 
                    xrst =  (snd tpl)
                 in [[x] ,(splitWith tf (tail xrst))]