$并不总是在Haskell中工作

Aft*_*ock 0 haskell

这是一个Haskell代码示例.

indentBrackets (c:rest) level
   | c=='('    = "\n" ++ (replicate level ' ') ++ [c]
                      ++ (indentBrackets rest (level+1))
   | c==')'    =  [c] ++ (indentBrackets rest (level-1))
   | c=='['    = "\n" ++ (replicate level ' ') ++ [c] 
                      ++ (indentBrackets rest (level+1))
   | c==']'    =  [c] ++ (indentBrackets rest (level-1))
   | otherwise =  [c] ++ (indentBrackets rest (level  ))

indentBrackets [] _ = ""
Run Code Online (Sandbox Code Playgroud)

如果我换otherwise = [c] ++ (indentBrackets rest (level))otherwise = [c] ++ $ indentBrackets rest (level),我明白了

src\Main.hs:182:25:输入`$'解析错误

不应该没问题吗?

pig*_*ker 14

是的,那不应该没问题.

$运营商是一个非常普通的管道符:你可以用它两者之间的表达式(分别为函数及其参数)或形成部分.它不正确的原因

[c] ++ $ indentBrackets rest (level)   -- parse error on input `$'
Run Code Online (Sandbox Code Playgroud)

++运算符是一个完全普通的中缀运算符:您可以在两个表达式(前缀及其后缀)之间使用它或形成一个.麻烦的是,这[c] ++不是表达.

如果您未经批准地决定使用$此特定应用程序,您可以通过制作一个部分来解决问题

([c] ++) $ indentBrackets rest (level)   -- should be fine
Run Code Online (Sandbox Code Playgroud)

额外的括号集([c] ++)界定了一个操作符部分,是一个未提供的中缀操作符,这里产生的函数仍在等待后缀.

  • 更一般地说,让两个运算符彼此相邻是一个解析错误:`..`` ++:``/*` (3认同)

lef*_*out 6

请注意,您不需要括号或$这里:你是什么形式的

a ++ (f b (c))
Run Code Online (Sandbox Code Playgroud)

现在,首先,c无所事事的parens c无论如何都是"原子的".

a ++ (f b c)
Run Code Online (Sandbox Code Playgroud)

接下来,记住在Haskell中如何处理多个参数:Currying,即

a ++ ((f b) c)
Run Code Online (Sandbox Code Playgroud)

让我们用g = f b一段时间......

a ++ (g c)
Run Code Online (Sandbox Code Playgroud)

好的,g c是一个简单的应用程序,函数/ lambda表达值.函数应用程序比任何中缀运算符绑定得更紧密,因此它与...相同

a ++ g c
Run Code Online (Sandbox Code Playgroud)

现在带回来 f

a ++ (f b) c
Run Code Online (Sandbox Code Playgroud)

再次移除currying托架,你最终得到

a ++ f b c
Run Code Online (Sandbox Code Playgroud)

或者,对于你的例子,

[c] ++ indentBrackets rest level
Run Code Online (Sandbox Code Playgroud)

如果我们将它应用于您的整个代码:

indentBrackets (c:rest) level
   | c=='('    = "\n" ++ replicate level ' ' ++ [c]
                      ++ indentBrackets rest (level+1)
   | c==')'    =  [c] ++ indentBrackets rest (level-1)
   | c=='['    = "\n" ++ replicate level ' ' ++ [c] 
                      ++ indentBrackets rest (level+1)
   | c==']'    =  [c] ++ indentBrackets rest (level-1)
   | otherwise =  [c] ++ indentBrackets rest  level
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我稍微减少了一点:

indentBrackets (c:rest) level
   | c `elem` "(["  = "\n" ++ replicate level ' '
                        ++ c : indentBrackets rest (level+1)
   | c `elem` ")]"  =  c : indentBrackets rest (level-1)
   | otherwise =  c : indentBrackets rest  level
Run Code Online (Sandbox Code Playgroud)