2009-12-16 5 views
5

Я играл с монад в F # (ака вычисления выражений), и я написал эту простую Удостоверение монады:Пользовательские вычисления выражения в 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 } 

Я не понимаю, ошибки я получаю в заметная линия:

Это выражение, как ожидается, имеет тип идентичности < «а>, но здесь имеет тип» Ь * «с

Я думаю, что это не имеет смысла, как GetInt() Я очевидно, значение типа Identity<'a>.

Может ли кто-нибудь сказать мне, что я делаю неправильно?

ответ

9

Синтаксис выражения вычисления хочет, чтобы Bind имел двоякий аргумент, а не карри. Так

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

См this article для всех подписей.

+1

Или см. Раздел 6.4.10 спецификации языка: http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html – Brian

+1

Примечание для себя: пересмотреть эту вики потому что это не имеет смысла;) – Juliet

3

Проблема заключается в типе вашей функции Bind - она ​​не должна принимать аргументы в валюте. Если вы измените его на:

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

то он должен работать.

Смежные вопросы