11

素晴らしい一連の投稿で、 Eric Lippert は、モナドのように振る舞い、それらのいくつかに対して return と bind を実装する、.NET 型のいわゆる「モナド パターン」の概要を説明しています。

モナド型の例として、彼は次のように述べています。

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

2 つの質問があります。

  1. これはHaskellNullable<T>のようなもので、いくつかのアクションをバインドすることは、いつでも失敗する可能性のある一連の操作を表します。リストモナド ( ) が非決定性を表していることは知っています。モナド(モナド )として何をするのかさえちょっと理解しています。と の単項セマトニクスとは? それらを束縛するとはどういう意味ですか?MaybeMaybeIEnumerable<T>FuncReaderLazy<T>Task<T>

  2. モナドのように振る舞う .NET の型の例は他にありませんか?

4

2 に答える 2

2

モナドのバインド関数には次の型があります。

Moand m => m a -> (a -> m b) -> m b

そのためTask<T>、C# ではTask<A>、値を抽出してバインド関数に渡す関数が必要です。タスクがエラーまたはキャンセルされた場合、複合タスクはエラーまたはキャンセルを伝達する必要があります。

これは、async を使用するとかなり簡単です。

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);
}

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);
}

と思います

return bindFunc(lazy.Value);

の値を積極的に評価するため無効なのでlazy、作成されたレイジーから値をアンラップする新しいレイジーを構築する必要があります。

于 2013-04-28T23:55:35.127 に答える