12

Witnesses made visible in FCS by dsyme · Pull Request #9510 · dotnet/fsharp · Gi...

 3 years ago
source link: https://github.com/dotnet/fsharp/pull/9510
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Contributor

alfonsogarciacaro commented on Jun 24

@dsyme I've built FCS from this branch and I'm testing it with Fable: https://github.com/fable-compiler/Fable/blob/1ed140e4ffacf232ca5d14e5bee2e48e5b1c3570/src/Fable.Transforms/FSharp2Fable.fs#L548-L562

It's working but I'm facing a couple of problems:

  • The index from WitnessArg doesn't seem to be reliable. Every time I've found the pattern is always -1, so I've to make a guess and assume it's 0 if the enclosing scope does contain witnesses.
  • When visiting some expressions the following line is throwing the exception: "The lists had different lengths. list2 is 1 element shorter than list1":
    let convertedArgs = (argExprs, argTypes) ||> List.map2 (fun expr expectedTy -> mkCoerceIfNeeded g expectedTy (tyOfExpr g expr) expr)

For example I get the exception when trying to parse any of the following texts (note the message always says "list2 is 1 element shorter than list1"):

type Point =
    { x: int; y: int }
    static member Zero = { x=0; y=0 }
    static member Neg(p: Point) = { x = -p.x; y = -p.y }
    static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y }

type MyNumber =
    | MyNumber of int
    static member Zero = MyNumber 0
    static member (+) (MyNumber x, MyNumber y) =
        MyNumber(x + y)
    static member DivideByInt (MyNumber x, i: int) =
        MyNumber(x / i)

type MyNumberWrapper =
    { MyNumber: MyNumber }

module ArrayTests =
    testCase "Array.average works with custom types" <| fun () ->
        [|MyNumber 1; MyNumber 2; MyNumber 3|] |> Array.average |> equal (MyNumber 2)

    testCase "Array.averageBy works with custom types" <| fun () ->
        [|{ MyNumber = MyNumber 5 }; { MyNumber = MyNumber 4 }; { MyNumber = MyNumber 3 }|]
        |> Array.averageBy (fun x -> x.MyNumber) |> equal (MyNumber 4)

    testCase "Array.sum with non numeric types works" <| fun () ->
        let p1 = {x=1; y=10}
        let p2 = {x=2; y=20}
        [|p1; p2|] |> Array.sum |> equal {x=3;y=30}

    testCase "Array.sumBy with non numeric types works" <| fun () ->
        let p1 = {x=1; y=10}
        let p2 = {x=2; y=20}
        [|p1; p2|] |> Array.sumBy Point.Neg |> equal {x = -3; y = -30}

    testCase "Array.sum with non numeric types works II" <| fun () ->
        [|MyNumber 1; MyNumber 2; MyNumber 3|] |> Array.sum |> equal (MyNumber 6)

    testCase "Array.sumBy with non numeric types works II" <| fun () ->
        [|{ MyNumber = MyNumber 5 }; { MyNumber = MyNumber 4 }; { MyNumber = MyNumber 3 }|]
        |> Array.sumBy (fun x -> x.MyNumber) |> equal (MyNumber 12)

I will try to convert these into tests for this repository and send a PR tomorrow.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK