F#解析器组合器

时间:2015-06-29 05:36:42

标签: parsing haskell f#

我正在尝试将有关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 ""
    }

如果我从else return ""方法中删除string,则结果始终为空列表。 在Haskell中,声明了字符串函数:

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

这很好用。 为什么F#功能不能按预期工作?

1 个答案:

答案 0 :(得分:0)

我的Haskell有点生疏,但是你发布的代码段不是你的F#代码,也就是在Haskell中,你需要一个基本案例来递归(空字符串)吗?

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