-
Notifications
You must be signed in to change notification settings - Fork 38
Open
Description
This bug is not about taking the wrong overload, which is an ongoing problem not easy to solve, but about returning a value not corresponding to any of the overloads.
I'm under the impression that overload resolution fails and then some buggy code returns a no sense value instead of a compile error.
Here's a repro
open System
type Default6 = class end
type Default5 = class inherit Default6 end
type Default4 = class inherit Default5 end
type Default3 = class inherit Default4 end
type Default2 = class inherit Default3 end
type Default1 = class inherit Default2 end
type [<Struct>]Result2<'T, 'E> = Ok2 of OkField:'T | Error2 of ErrorField:'E
type Bind =
static member (>>=) (source: Lazy<'T> , f: 'T -> Lazy<'U> ) = lazy (f source.Value).Value : Lazy<'U>
static member (>>=) (source: seq<'T> , f: 'T -> seq<'U> ) = Seq.collect f source : seq<'U>
static member (>>=) (source , f: 'T -> _ ) = Option.bind f source : option<'U>
static member (>>=) (source , f: 'T -> _ ) = List.collect f source : list<'U>
static member (>>=) (source , f: 'T -> _ ) = Array.collect f source : 'U []
static member (>>=) (source , f: 'T -> _ ) = async.Bind (source, f) : Async<'U>
static member (>>=) (source , k: 'T -> _ ) = Result.bind k source : Result<'U,'E>
static member (>>=) (source: Result2<'T,'E> , k: 'T -> Result2<'U,'E>) = Unchecked.defaultof<_> : Result2<'U,'E>
static member inline Invoke (source: '``Monad<'T>``) (binder: 'T -> '``Monad<'U>``) : '``Monad<'U>`` =
let inline call (_mthd: 'M, input: 'I, _output: 'R, f) = ((^M or ^I or ^R) : (static member (>>=) : _*_ -> _) input, f)
call (Unchecked.defaultof<Bind>, source, Unchecked.defaultof<'``Monad<'U>``>, binder)
type Return =
inherit Default1
static member inline InvokeOnInstance (x: 'T) = (^``Applicative<'T>`` : (static member Return : ^T -> ^``Applicative<'T>``) x)
static member inline Invoke (x: 'T) : '``Applicative<'T>`` =
let inline call (mthd: ^M, output: ^R) = ((^M or ^R) : (static member Return : _*_ -> _) output, mthd)
call (Unchecked.defaultof<Return>, Unchecked.defaultof<'``Applicative<'T>``>) x
static member Return (_: seq<'a> , _: Default2) = fun x -> Seq.singleton x : seq<'a>
static member inline Return (_: 'R , _: Default1) = fun (x: 'T) -> Return.InvokeOnInstance x : 'R
static member Return (_: Lazy<'a> , _: Return ) = fun x -> Lazy<_>.CreateFromValue x : Lazy<'a>
static member Return (_: option<'a> , _: Return ) = fun x -> Some x : option<'a>
static member Return (_: list<'a> , _: Return ) = fun x -> [ x ] : list<'a>
static member Return (_: 'a [] , _: Return ) = fun x -> [|x|] : 'a []
static member Return (_: 'a Async , _: Return ) = fun (x: 'a) -> async.Return x
static member Return (_: Result<'a,'e> , _: Return ) = fun x -> Ok x : Result<'a,'e>
static member Return (_: ResizeArray<'a>, _: Return ) = fun x -> ResizeArray<'a> (Seq.singleton x)
type Delay =
inherit Default1
static member inline Delay (_mthd: Default3, x: unit-> ^``Monad<'T>`` when ^``Monad<'T>`` : struct , _: Default2) = Bind.Invoke (Return.Invoke ()) x : ^``Monad<'T>``
static member inline Delay (_mthd: Default4, x: unit-> ^``Monad<'T>`` when ^``Monad<'T>`` : not struct , _: Default1) = Bind.Invoke (Return.Invoke ()) x : ^``Monad<'T>``
static member Delay (_mthd: Default2, x: unit-> _ , _ ) = Seq.delay x : seq<'T>
static member Delay (_mthd: Default2, x: unit-> 'R -> _ , _ ) = (fun s -> x () s): 'R -> _
static member inline Invoke (source : unit -> '``Monad<'T>``) : '``Monad<'T>`` =
let inline call (mthd: ^M, input: unit -> ^I) = ((^M or ^I) : (static member Delay : _*_*_ -> _) mthd, input, Unchecked.defaultof<Delay>)
call (Unchecked.defaultof<Delay>, source)
let res = Delay.Invoke (fun () -> [5] )
printfn "res is %A" res
Running this prints res is [object Object]
, but if we comment out the first overload of Delay, we get res is [5]
which is the expected result.
Not sure, but it seems to be a problem when there are constraints in the overload, like not struct
.
Metadata
Metadata
Assignees
Labels
No labels