P # combinators

I am trying to translate an example about monadic parsers ( https://www.cs.nott.ac.uk/~gmh/pearl.pdf ) into F #.

So far I:

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 else return ""from the method string, then the result will always be empty. Haskell declares a string function:

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

and it works fine. Why is the F # function not working as expected?

+4
source share
1 answer

My Haskell is a little rusty, but not the fragment you posted is equivalent to your F # code, i.e. in Haskell, do you need a base case for recursion (empty string)?

else, (.. , ), ( "), . " ", .

0

All Articles