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

To create the 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 redundant. It would be better if I could write Seq.map(MyInt)

But I can not. One way to solve this problem is to define a single function

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

Is there a better way to do this?

+6
source share
4 answers

In short, no.

Object constructors are not first-class features in F #. This is another reason not to use classes, it's better to use discriminatory unions here:

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

If you don't like explicit shortcuts, the sequence expression looks better in your example:

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

Alternatively, your decision is a good decision.

+7
source

If the hopeless hacks do not bother you, you can 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 xi = i [0..9] |> List.map New<MyInt, _> 

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

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

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

+9
source

To report this, F # 4.0 updated the constructors to first-class functions, so now they can be used anywhere in the function or the method can be used.

+1
source

I use static methods for this purpose. The reason is that sometimes your object constructor needs two arguments taken from different sources, and my approach allows using List.map2 :

 type NumRange(value, range) = static member Make aValue aRange = new NumRange(aValue, aRange) let result1 = List.map2 NumRange.Make values ranges 

A partial application is also not prohibited:

 let result2 = values |> List.map NumRange.Make |> List.map2 id <| ranges 

If you don't like using id here, you can use (fun xy -> xy) , which is more readable.

0
source

Source: https://habr.com/ru/post/912874/


All Articles