Пользовательские выражения вычислений в F # - PullRequest
5 голосов
/ 16 декабря 2009

Я играл с монадами в F # (иначе говоря, вычислительные выражения) и написал эту простую монаду Identity:

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 }

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

Ожидалось, что это выражение будет иметь тип Identity <'a>, но здесь имеет тип' b * 'c

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

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

Ответы [ 2 ]

9 голосов
/ 16 декабря 2009

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

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

См. эту статью для всех подписей.

3 голосов
/ 16 декабря 2009

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

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

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

...