【问题标题】:F# parser combinatorsF# 解析器组合器
【发布时间】:2015-09-15 11:47:46
【问题描述】:

我正在尝试将有关 monadic 解析器 (https://www.cs.nott.ac.uk/~gmh/pearl.pdf) 的示例翻译成 F#。

到目前为止我有:

type Parser<'a> = Parser of  (string -> ('a*string) list)

let item : Parser<char> =
  Parser (fun (s:string) -> 
                match s with
                | "" -> []
                | null -> []
                | _ -> (s.Chars(0),s.Substring 1)::[])

let sat (pred : (char -> bool)) : Parser<char> =
  parserWf
    {
       let! c = item
       if pred c then return c
    }

let char c : Parser<char> =
  sat (fun c' -> c'.Equals(c))

let rec string (str:string) : Parser<string> =
  parserWf
    {
        if (str.Length > 0)
        then
            let! c = char (str.Chars 0)
            let! cs = string (str.Substring 1)
            printfn "String: %s" cs
            return c.ToString() + cs
        else
            return ""
    }

如果我从string 方法中删除else return "",那么结果总是空列表。 在 Haskell 中声明了字符串函数:

string :: String -> Parser String
string "" = return ""
string (c:cs) = do {char c; string cs; return (c:cs)}  

这很好用。 为什么 F# 函数没有按预期工作?

【问题讨论】:

  • 您应该展开“不起作用”。类型错误?运行时错误?结果错误?
  • “为什么 F# 函数没有按预期工作 [当我删除 else return ""]?”嗯......这很大程度上取决于你的期望。也许你应该说那是什么。
  • 如果我删除字符串函数的最后两行(否则返回“”)。然后,如果我执行 'runParser (string "hello") "hello!",在 F# 中我得到空列表,但在 Haskell 中我得到 [("hello","!")]。

标签: parsing haskell f#


【解决方案1】:

我的 Haskell 有点生疏了,但是您发布的 sn-p 是否不等同于您的 F# 代码,即在 Haskell 中,您也需要递归的基本情况(空字符串)?

如果你删除 else 部分,倒数第二个对字符串的调用(即只剩下一个字符的那个)将不会从它的递归调用中得到任何结果(传递“”),所以它不会返回任何有效结果好吧。然后这会“向上”传播,您最终会得到一个空列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2020-01-17
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多