Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# - Can I use type name as a function which acts as the default constructor?

Tags:

f#

To create a sequence of my class,

type MyInt(i:int) =
    member this.i = i

[1;2;3] |> Seq.map(fun x->MyInt(x))

where fun x->MyInt(x) seems to be redundant. It would be better if I can write Seq.map(MyInt)

But I cannot. One workaround I can think of is to define a separate function

let myint x = MyInt(x)
[1;2;3] |> Seq.map(myint)

Is there a better way to do this?

like image 736
woodings Avatar asked Apr 10 '12 18:04

woodings


2 Answers

If gratuitous hacks don't bother you, you could do:

///functionize constructor taking one arg
let inline New< ^T, ^U when ^T : (static member ``.ctor`` : ^U -> ^T)> arg =
  (^T : (static member ``.ctor`` : ^U -> ^T) arg)

type MyInt(i: int) =
  member x.i = i

[0..9] |> List.map New<MyInt, _>

EDIT: As kvb pointed out, a simpler (and less hacky) signature can be used:

let inline New x = (^t : (new : ^u -> ^t) x)

Note, this switches the type args around, so it becomes New<_, MyInt>.

like image 58
Daniel Avatar answered Nov 15 '22 10:11

Daniel


In short, no.

Object constructors aren't first-class functions in F#. This is one more reason to not use classes, discriminated unions is better to use here:

type myInt = MyInt of int
let xs = [1;2;3] |> Seq.map MyInt

If you don't like explicit lambdas, sequence expression looks nicer in your example:

let xs = seq { for x in [1;2;3] -> MyInt x }

Alternatively, your workaround is a nice solution.

like image 45
pad Avatar answered Nov 15 '22 12:11

pad