views:

234

answers:

1

While migrating some code to the latest version of F#, included in VS2010 b1, I've encountered an issue and I'd like to know if there's a workaround available and - if not - why was the behavior of the F# compiler modified not to support the scenario.


type Foo(a) =
    [<OverloadID("CurriedAbc")>]
    member public x.Abc (p:(oneType * anotherType) seq) otherParm = method impl...

    //this overload exists for better compatibility with other languages
    [<OverloadID("TupledAbc")>]
    member public x.Abc (p:Dictionary<oneType, anotherType>, otherParm) =
        x.Abc(p |> Seq.map(fun kvp -> (kvp.Key, kvp.Value))) otherParm

This code produces the following compile-time error:

error FS0191: One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form

Please mind that this used to work flawlessly on F# 1.9.6.2 (Sept. CTP)

+4  A: 

The reason for the change is in the detailed release notes:

Optimizations for Curried Methods

A curried member looks like this:

type C() =

static member Sum a b = a + b

In previous implementations of F# curried members were compiled less efficiently than non-curried members. This has now been changed. However, there are now some small restrictions on the definition of curried members:

  • curried members may not be overloaded
  • some definitions of curried members may need to be adjusted to add the correct number of parameters to the definition

Since your overloading can be resolved only on the first parameter, you should be able to work round it by changing the curried version to:

    [<OverloadID("CurriedAbc")>]
    member public x.Abc (p:(oneType * anotherType) seq)
       = fun otherParm -> method impl...
Ganesh Sittampalam
Thanks for pointing out the title issue, I was writing a question for another problem which I got to fix and then this one came up and I just forgot about the title :(P.S.: I'm testing your solution right now to see if it works :D
emaster70