Using the F# pipe symbol with an object constructo

2019-01-26 05:17发布

问题:

I'm trying to figure out the correct syntax to use the pipe operator |> into the creation of an object. Currently I'm using a static member to create the object and just piping to that. Here is the simplified version.

type Shape = 
    val points : Vector[]

    new (points) =
        { points = points; }

    static member create(points) =
        Shape(points)

    static member concat(shapes : Shape list) =
        shapes
            |> List.map (fun shape -> shape.points)
            |> Array.concat
            |> Shape.create

What I want to do ...

    static member concat(shapes : Shape list) =
        shapes
            |> List.map (fun shape -> shape.points)
            |> Array.concat
            |> (new Shape)

Is something like this possible? I don't want to duplicate code by repeating my constructor with the static member create.

Update Constructors are first-class functions as of F# 4.0

In F# 4.0 the correct syntax is.

    static member concat(shapes : Shape list) =
        shapes
            |> List.map (fun shape -> shape.points)
            |> Array.concat
            |> Shape

回答1:

There's always

(fun args -> new Shape(args))


回答2:

Apparently, object constructors aren't composable. Discriminated union constructors don't seem to have this problem:

> 1 + 1 |> Some;;
val it : int option = Some 2

If you want to use the pipeline, Brian's answer is probably best. In this case, I'd consider just wrapping the entire expression with Shape( ).