简体   繁体   English

F#解析器组合器

[英]F# parser combinators

I'm trying translate the example about monadic parsers ( https://www.cs.nott.ac.uk/~gmh/pearl.pdf ) to F#. 我正在尝试将关于monadic解析器( https://www.cs.nott.ac.uk/~gmh/pearl.pdf )的示例翻译成F#。

So far I have: 到目前为止,我有:

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 ""
    }

If I remove the else return "" from the string method then the result is always the empty list. 如果我从string方法中删除else return "" ,那么结果始终是空列表。 In Haskell the string function is declared: 在Haskell中声明了字符串函数:

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

and this works just fine. 这很好用。 Why does the F# function not work as expected? 为什么F#功能不能按预期工作?

My Haskell is a bit rusty, but isn't the snippet you posted equivalent to your F# code, ie in Haskell too, you need a base case for the recursion (the empty string)? 我的Haskell有点生疏,但是你发布的代码片段不是你的F#代码,也就是在Haskell中,你需要一个基本案例来进行递归(空字符串)?

If you remove the else part, the second to last call to string (ie the one with just one character left) will get no result from its recursive call (passing ""), so it'll return no valid result as well. 如果删除else部分,对字符串的倒数第二次调用(即只剩下一个字符的那个)将不会从其递归调用中得到任何结果(传递“”),因此它也不会返回任何有效结果。 This then propagates 'upwards' and you'll end up with an empty list. 然后它会向上传播,你最终会得到一个空列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM