2009-12-16 8 views
5

Ich habe mit Monaden in F # liebäugelt (aka Berechnung Ausdrücke) und ich schrieb diese einfache Identität Monade:Individuelle Berechnung Ausdrücke in F #

type Identity<'a> = 
    | Identity of 'a 

type IdentityBuilder() = 
    member x.Bind (Identity v) f = f(v) 
    member x.Return v = Identity v 
let identity = new IdentityBuilder() 

let getInt() = identity { return Int32.Parse(Console.ReadLine()) } 

let calcs() = identity { 
    let! a = getInt() // <- I get an error here 
    let! b = getInt() 
    return a + b } 

Ich verstehe nicht den Fehler, den ich in der immer bin markierte Zeile:

Dieser Ausdruck wurde erwartet Typ Identität < haben 'a> aber hier hat Typ' b * ‚c

ich denke, das keinen Sinn, da getInt macht() i s eindeutig ein Wert vom Typ Identity<'a>.

Kann mir jemand sagen, was mache ich falsch?

Antwort

9

Die Berechnung Ausdruck Syntax will Bind zu einem Tupel, nicht Curry-Argument. So

member x.Bind((Identity v), f) = f(v) 

Siehe this article für alle Signaturen.

+1

Oder siehe Abschnitt 6.4.10 der Sprachspezifikation: http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html – Brian

+1

Hinweis zu sich selbst: revidiere das Wiki Seite, weil es keinen Sinn macht;) – Juliet

3

Das Problem ist der Typ Ihrer Bind Funktion - es sollte nicht curried Argumente. Wenn Sie es ändern in:

member x.Bind (Identity v, f) = f(v) 

dann sollte es funktionieren.