Skip to content

Instantly share code, notes, and snippets.

@sgtz
Created October 9, 2014 12:39
Show Gist options
  • Save sgtz/48ca8ade6d4df3a2fddc to your computer and use it in GitHub Desktop.
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
Copy link

dsyme commented Oct 9, 2014

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
Copy link
Author

sgtz commented Oct 9, 2014

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