Reputation: 7693
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?
Upvotes: 6
Views: 381
Reputation: 6629
To give an update on this - F# 4.0 has upgraded constructors to first-class functions, so they can now be used anywhere a function or method can be used.
Upvotes: 1
Reputation: 47914
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>
.
Upvotes: 9
Reputation: 7735
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 you to use List.map2
:
type NumRange(value, range) =
static member Make aValue aRange = new NumRange(aValue, aRange)
let result1 = List.map2 NumRange.Make values ranges
Partial application is not prohibited as well:
let result2 =
values
|> List.map NumRange.Make
|> List.map2 id <| ranges
If you dislike using id
here, you may use (fun x y -> x y)
which is more readable.
Upvotes: 0
Reputation: 41290
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.
Upvotes: 7