Reputation: 887
First off, I have a better method of dealing with this issue so it's not a problem.
However, it is something that I don't understand. Can someone explain this?
When I define the swap function as:
namespace Utilities
module Misc
let Swap (left : 'a byref) (right : 'a byref) =
let temp = left
left <- right
right <- temp
I am able to use the Swap function like this just fine.
Misc.Swap (&s.[i]) (&s.[j])
But when I define the module like:
namespace Utilities
type Misc =
static member Swap (left : 'a byref) (right : 'a byref) =
let temp = left
left <- right
right <- temp
I get the following error on both arguments:
This expression has type 'b byref but is here used with type 'a ref
How did the type inference for the caller's arguments change by moving the function into a type?
Upvotes: 2
Views: 188
Reputation: 1503
This may be an interaction with the tuple transformation that the F# compiler performs on class methods.
Reflector reports the type of Misc.Swap
as:
public static void Swap<a>(ref a left, ref a right);
so we can see here that the compiler has transformed the curried arguments into tupled form.
Defining the method with tupled arguments avoids this problem:
type Misc =
static member Swap(left : 'a byref, right : 'a byref) =
let temp = left
left <- right
right <- temp
> let s = Array.init 3 (fun i -> i)
> val s : int array = [|0; 1; 2|]
> Misc.Swap (&s.[2], &s.[0])
> s;;
> val s : int array = [|2; 1; 0|]
Upvotes: 2