Jack Fox
Jack Fox

Reputation: 945

".NET" and "OCaml" formatting of signatures

F# allows ".NET" and "OCaml" formatting of signatures. This can be confusing when you fall into the habit of using one style, and then find a situation where you cannot properly format the signature you need. Consider this code, which requires a flexible type as the output of the function input to foo:

let foo n (bar: int -> #seq<'a>) =
    (fun () -> Vector.ofSeq (bar n))

let foobar n = Array.ofSeq([1..n])

let x = foo 10 foobar

I could not figure out how to express #seq<'a> in OCaml format. Is it possible?

Upvotes: 3

Views: 183

Answers (2)

Alex
Alex

Reputation: 2040

I'm not exactly sure what you mean, but I assume that you want to put the type variable in front of the type name, e.g. 'a #seq.

According to the language specification (§5.1.5) it's not possible since:

A type of the form #type is an anonymous type with a subtype constraint and is equivalent to 'a when 'a :> type, where 'a is a fresh type inference variable.

So you could write your type like: 'a when 'a :> seq<'b>.

EDIT: You could actually use #('a seq), but it looks awkward and I doubt it's what you want.

EDIT2: Didn't see Ramon Snir's answer :).

Upvotes: 1

Ramon Snir
Ramon Snir

Reputation: 7560

The following compiles just fine:

type A<'a>(x) =
    member __.Get : 'a = x
    abstract PairWith : 'b -> ('a * 'b * int)
    default __.PairWith y = x, y, 1

type B<'a>(x) =
    inherit A<'a>(x)
    override __.PairWith y = x, y, 2

let pairAB (x : #A<'a>) y =
    x, x.PairWith y

type 'a X (x) =
    member __.Get : 'a = x
    abstract PairWith : 'b -> ('a * 'b * int)
    default __.PairWith y = x, y, 1

type 'a Y (x) =
    inherit X<'a>(x)
    override __.PairWith y = x, y, 2

let pairXY (x : #('a X)) y =
    x, x.PairWith y

So you can guess (and then confirm with F# Interactive) that you are looking for #('a seq).

Upvotes: 4

Related Questions