将循环转换为Maybe monad

时间:2015-06-08 14:47:31

标签: c# functional-programming maybe

最近,我尝试使用Maybe monad库在我的C#代码中应用this模式。

我发现难以理解的是将这样的功能转换为可能的范例:

public Maybe<object> DoSomething(IReader reader)
{
    while (true)
    {
        var result = reader.Read();
        if (result == null) return Maybe<object>.Nothing;
        if (result.HasValue) return new Maybe<object>(null);
    }
}

我想用from x in X表格写一下。此函数后面的功能是读取IReader,直到它返回值(Maybe有值)或发生错误(null返回)。

1 个答案:

答案 0 :(得分:0)

你的评论/问题的答案是:你没有 - 是的,你可以尝试使用递归调用,但这可能会在C#中失败,而你在使用时更好

from x in X只是 monadic - bind (它被翻译成SelectMany函数)并且在LINQ语法中没有直接的方法此

但你可以这样编写自己的函数:

public tValue DoUntilSome<tValue>(Func<Maybe<tValue>> f)
{
    while (true)
    {
        var x = f();
        if (x.HasValue) return x.Value;
    }
}

并打电话(见下文)

var result = DoUntilSome(() => TryRead(reader));

备注

首先Maybe<object>object)部分是一种气味 - 因为你肯定想要一个具体类型而不是通用object

然后new Maybe<object>(null) 非常也很奇怪

我会提出类似的建议:

public Maybe<tValue> TryRead<tValue>(IReader reader)
{
    var result = reader.Read();
    if (result == null || !result.HasValue) 
        return Maybe<tValue>.Nothing;
    return new Maybe<tValue>((tValue)reader.Value);
}

然后当然这部分是为了得到一些Maybe值 - 你试图用from x in X做的事情是monadic-bind - 你只能使用一次你有Maybe开头:

from value in TryRead<tValue>(reader)
from other in TrySomethingDifferent(value) // here is the bind
select .... 

声明

我没有编译任何这些(因为我懒得下载github项目和东西) - 让你应该能够轻松解决任何可能隐藏在那里的语法错误 - 抱歉

如果您遇到重大问题,请发表评论