Skip to content

Instantly share code, notes, and snippets.

@sgtz
Created October 9, 2014 12:39
Show Gist options
  • Select an option

  • Save sgtz/48ca8ade6d4df3a2fddc to your computer and use it in GitHub Desktop.

Select an option

Save sgtz/48ca8ade6d4df3a2fddc to your computer and use it in GitHub Desktop.
Possible F# Type Inference Bug In Workaround Form
// NB. to reproduce bug, delete the type after the colon
module AST =
type name = string
type param = string
type arg = Number of int | Arg of param
type Part =
| Cell of string
module Parser
open AST
open FParsec
let test p str =
match run p str with
| Success(result, _, _) -> printfn "Success: %A %O" result (result.GetType())
| Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg
let proc : ref<(((string * string) list) list)> = ref []
let one : Parser<string,unit> = pstring "1"
let two : Parser<string,unit> = pstring "2"
let three : Parser<Part,unit> = pstring "2" |>> fun s->Part.Cell(s)
test one "1"
let pNumberWord = one <|> two |>> fun a->Part.Cell(a)
test pNumberWord "2"
@dsyme

dsyme commented Oct 9, 2014

Copy link
Copy Markdown

The annotations "Parser<string,unit>" on "one" and "two" are needed because of the value restriction - "pstring" is generic, returning "Parser<string,'T>" for any 'T, and you need to pin down an exact non-generic value for 'T when using it to create parser values like this.

The annotation on "three" is needed for the same reason, though the hidden "T" implied by the use of "pstring" is not so easy to spot.

@sgtz

sgtz commented Oct 9, 2014

Copy link
Copy Markdown
Author

Some of the library specific demos / documentation suggested otherwise. That's good news. Thanks Don! Much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment