Rune FS
Rune FS

Reputation: 21752

Confusing error message "Expected type unit but was X"

I'm either not seeing something obvious or just generally confused The code I have looks like:

let inline createContext source destination  =
    let src = (fun amount (s:^T) -> (^T : (member DecreaseBalance : decimal -> ^a) (s, amount)))
    let dst = (fun amount (d:^T) -> (^T : (member IncreaseBalance : decimal -> ^a) (d, amount)))
    let log = (fun msg a -> (^T : (member LogMessage : string -> ^a) (a, msg)))
    let f = fun amount -> src amount source |> ignore
                          log "" source |> ignore
    let f = fun amount -> dst amount destination |> ignore
                          log "" destination |> ignore
    new Context (source, destination, src, dst, log)
let src = new Account(0m)
let dst = new Account(0m)
let ctxt = createContext src dst

The type Account fullfils the member constraints of createContext. Intellisense claims the signartur of createContext to be Account -> Account -> Context but the compiler complains at src in the last line with "This expression was expected to have type unit but here has type Account" Any idea of what I'm missing?

If I rename a member function of Account so it no longer meets the constraints I get "The type 'Account' does not support any operators named 'LogMessage'" which is what I would expect in that scenario. I get the same error message if I pass () as the first argument. That unit doesn't support LogMessage (not that it would bring me any good if that actually compiled)

Upvotes: 0

Views: 459

Answers (1)

Daniel
Daniel

Reputation: 47914

This compiles fine for me, given the following types

type Context(a, b, c, d, e) = class end
type Account(a) = 
  member __.DecreaseBalance(a) = Unchecked.defaultof<_>
  member __.IncreaseBalance(a) = Unchecked.defaultof<_>
  member __.LogMessage(a) = Unchecked.defaultof<_>

I suspect something else is going on. Can you show more of the code?

It's strange that createContext is inferred to be Account -> Account -> Context. I would expect 'T -> 'T -> Context ('T requires member DecreaseBalance and IncreaseBalance and LogMessage). That may or may not be a clue to your problem.

If possible, replace the static member constraints with an interface.

Upvotes: 1

Related Questions