将循环转换为 Maybe monad
Convert loop to Maybe monad
最近我尝试应用 Maybe monad pattern in my C# code using this 库。
我发现难以掌握的是将这样的函数转换为 Maybe 范式:
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
直到它 returns 一个值(Maybe
有一个值)或发生错误(返回 null
)。
你的 comment/question 的答案是:你不会 - 是的你可以尝试使用递归调用但是这在 C# 中可能会失败并且你更好地使用 while
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 项目和东西) - 你应该能够轻松解决可能隐藏在那里的任何语法错误 - 抱歉
如果您遇到重大问题,请发表评论
最近我尝试应用 Maybe monad pattern in my C# code using this 库。
我发现难以掌握的是将这样的函数转换为 Maybe 范式:
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
直到它 returns 一个值(Maybe
有一个值)或发生错误(返回 null
)。
你的 comment/question 的答案是:你不会 - 是的你可以尝试使用递归调用但是这在 C# 中可能会失败并且你更好地使用 while
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 项目和东西) - 你应该能够轻松解决可能隐藏在那里的任何语法错误 - 抱歉
如果您遇到重大问题,请发表评论