【问题标题】:Haskell parser error in where clause在 where 子句中的 Haskell 解析器错误
【发布时间】:2009-01-05 11:14:23
【问题描述】:

第一个 where 部分中的 rs 定义有什么问题?

palindrome :: [a] -> [a]

palindrome xs = con xs rs
    where con a b = rev (rev a []) b
        rs = rev xs                        -- here
        where rev [] rs = rs
            rev (x:xs) rs = rev xs (x:rs)

我只是在学习 Haskell,但它的语法规则让我感到困惑。错误信息是

[1 of 1] Compiling Main             ( pelindrome.hs, interpreted )

pelindrome.hs:5:8: parse error on input `rs'

【问题讨论】:

    标签: syntax haskell


    【解决方案1】:

    你的缩进是错误的,我认为你只能有一个where (我可能错了。我不是一个haskell 人)。对rev 的调用也缺少一个参数(一个空列表):

    palindrome :: [a] -> [a]
    palindrome xs = con xs rs
        where con a b = rev (rev a []) b
              rs = rev xs []                       -- here
              rev [] rs = rs
              rev (x:xs) rs = rev xs (x:rs)
    
    main = print (palindrome "hello")
    

    打印出来:

    "helloolleh"
    

    我现在要试着理解它。不管怎样,玩得开心!

    编辑:现在对我来说很有意义。我认为这是正确的版本。有关 Haskell 缩进规则,请阅读 Haskell Indentation

    【讨论】:

    • 你说得对,rs 必须与上一行的 con 在同一列开始。这是一个奇怪的规则。
    • 并不奇怪:相同的句法级别 -> 相同的缩进
    • 您可以使用大括号“打破”该规则
    【解决方案2】:

    @litb: 你可以改写 con 的方式

    palindrome :: [a] -> [a]
    palindrome xs = con xs rs
        where con [] b = b
              con (x:xs) b = x:con xs b
              rs = rev xs []                       -- here
              rev [] rs = rs
              rev (x:xs) rs = rev xs (x:rs)
    

    这就是 ++ 在 prelude 中的实现方式。我以前的版本是如何以尾调用方式(例如 Erlang)用非惰性函数或逻辑语言编写它。

    【讨论】:

    • 我认为 (++) 被定义为 (++) = flip $ foldr (:) - 反正我就是这样写的。
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 2017-08-16
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多