TemplateHaskell 未安装...那么它是

TemplateHaskell not installed... then it is

我在Haskell写程序,里面有很多括号。因此,为了清理这个难看的烂摊子,我使用了几次 $ 运算符以使其更易于阅读。例如:

longFunc arg1 (anotherFunc (yetAnotherFunc arg2))

替换为

longFunc arg1 $ anotherFunc $ yetAnotherFunc arg2

但是当我使用 GHCi 编译我的程序时,我收到一条消息说:

MyFile.hs:18:18: error:
    parse error on input ‘$’
    Perhaps you intended to use TemplateHaskell
Failed, modules loaded: none.

这是第 16-18 行:

isDigit :: Char -> Bool
isDigit c =
  c `elem` $ ['0'..'9'] ++ "."

我很困惑,因为我已经多次使用 $ 运算符(使用相同的编译器),如下所示:

main = putStrLn $ show 42

所以我将该代码作为测试输入到我的文件中,删除了其他 $ 处,然后加载它。

成功了!

谁能告诉我这是怎么回事?

不能在另一个中缀运算符后立即使用 ($)。第 18 行:

c `elem` $ ['0'..'9'] ++ "."

需要改写为以下选项之一:

  1. 括号保持原样:

    c `elem` (['0'..'9'] ++ "."])
    
  2. ($)应用于elem的一片:

    (c `elem`) $ ['0'..'9'] ++ "."
    
  3. 将对 elem 的调用转换为前缀调用:

    elem c $ ['0'..'9'] ++ "."
    

我推荐选项 3。连续的中缀运算符(在本例中为 `elem`$)没有明确定义的优先级并且会混淆解析器。一般的经验法则是,中缀运算符的每一侧都必须始终具有完整的表达式。 c `elem`不是一个完整的表达式,所以不能在$的左边。同样,$ ['0'..'9'] ++ "."不是一个完整的表达式,所以不允许在`elem`的右边。