Monadic .NET类型

Mic*_*ael 11 .net c# monads haskell

在一系列帖子中, Eric Lippert概述了.NET类型的所谓"Monad模式",它有点像monad和implements实现返回并绑定其中一些.

作为monadic类型的例子,他给出了:

  • Nullable<T>
  • Func<T>
  • Lazy<T>
  • Task<T>
  • IEnumerable<T>

我有两个问题:

  1. 我得到Nullable<T>的有点像MaybeHaskell,绑定几个Maybe动作代表一组可能在任何时候都失败的操作.我知道列表monad(IEnumerable<T>)代表非决定论.我甚至有点明白Func作为monad(Readermonad)的作用.什么是monadic sematnics Lazy<T>Task<T>?绑定它们意味着什么?

  2. 有没有人在.NET中有更多类型的例子呢?

Lee*_*Lee 2

一元绑定函数的类型为:

Moand m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

因此,Task<T>在 C# 中,您需要一个函数来提取Task<A>值并将其传递给绑定函数。如果任务出错或被取消,复合任务应传播错误或取消。

使用异步,这相当简单:

public static async Task<B> SelectMany<A, B>(this Task<A> task, Func<A, Task<B>> bindFunc)
{
    var res = await task;
    return await bindFunc(res);
}
Run Code Online (Sandbox Code Playgroud)

因为Lazy<T>您应该从一个函数创建一个惰性值,该函数采用另一个惰性计算的结果:

public static Lazy<B> SelectMany<A, B>(this Lazy<A> lazy, Func<A, Lazy<B>> bindFunc)
{
    return new Lazy<B>(() => bindFunc(lazy.Value).Value);
}
Run Code Online (Sandbox Code Playgroud)

我觉得

return bindFunc(lazy.Value);
Run Code Online (Sandbox Code Playgroud)

是无效的,因为它急切地评估 的值,lazy因此您需要构造一个新的惰性函数,它将从创建的惰性函数中解开值。