Showing posts with label quirks. Show all posts
Showing posts with label quirks. Show all posts

Wednesday, March 4, 2009

F# Quirks

A feature or a bug?

An innocent-looking pair of parentheses ends up influencing the runtime representation of discriminated union types.

I would prefer not to have this. The two representations seem conceptually redundant, it would be better to just pick the faster one.

Given this foo.fs:

#light

open Microsoft.FSharp.Reflection

type A1 = A1 | B1 of (A1 * A1)

type A2 = A2 | B2 of A2 * A2


printfn "%A" ((FSharpType.GetUnionCases(typeof<A1>)
              |> Array.map (fun x -> x.GetFields())));;

printfn "%A" ((FSharpType.GetUnionCases(typeof<A2>)
              |> Array.map (fun x -> x.GetFields())));;

Run fsi --quiet --exec foo.fs to produce this:

[|[||]; [|Microsoft.FSharp.Core.Tuple`2[FSI_0001.Foo+A1,FSI_0001.Foo+A1] B11|]|]
[|[||]; [|FSI_0001.Foo+A2 B21; FSI_0001.Foo+A2 B22|]|]

I found this code while testing a library that produced different results depending on the presence or absence of the parentheses.

Update: A feature! Thanks to Zedd. I should know my specs and my OCaml:

Objective Caml version 3.10.2
# type c = C of int * int;;
type c = C of int * int
# match C(1, 2) with | C x -> x;;
The constructor C expects 2 argument(s), but is here applied to 1 argument(s)
# type c = C of (int * int);;
type c = C of (int * int)
# match C(1, 2) with | C x -> x;;
- : int * int = (1, 2)
#