29

...これらすべての新しい(そしてIEnumerableを数えればそれほど新しいものではない)モナド関連のもので?

interface IMonad<T>
{
 SelectMany/Bind();
 Return/Unit();
}

これにより、任意のモナディックタイプで動作する関数を作成できます。それともそれほど重要ではありませんか?

4

2 に答える 2

65

IMonad<T>のメソッドの署名がどうあるべきかを考えてみてください。Haskell では、Monad 型クラスは次のように定義されています。

class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  return :: a -> m a

ISpecificMonad<a>一般的な IMonad インターフェイスの定義内で、特定の実装サブタイプ (「m a」または ) を参照できるようにする必要があるため、これを C# インターフェイスに直接変換するのは困難です。わかりました、 (たとえば)直接IEnumerable<T>実装しようとする代わりにIMonad<T>、特定のモナド型インスタンスとともに、モナドとして扱う必要があるものに渡すことができる別のオブジェクトに IMonad 実装を分解してみます (これは「辞書渡しスタイル」です)。これは になりIMonad<TMonad>、ここの TMonad は T inIEnumerable<T>ではなく、IEnumerable<T>それ自体になります。しかし、待ってください-これも機能しません。Return<T>たとえば、の署名は、任意の型 T から aに取得する必要TMonad<T>があるため TMonad<>. IMonad は次のように定義する必要があります

interface IMonad<TMonad<>> {

    TMonad<T> Unit<T>(T x);
    TMonad<U> SelectMany<T, U>(TMonad<T> x, Func<T, TMonad<U>> f);
}

型コンストラクター(TMonad<> など) をジェネリック型パラメーターとして使用できる仮想的な C# 機能を使用します。しかしもちろん、C# にはこの機能(高カインド ポリモーフィズム)はありません。実行時に型コンストラクターを具体化することはできますが ( typeof(IEnumerable<>))、パラメーターを指定せずに型シグネチャでそれらを参照することはできません。したがって、-100 ポイントのほかに、これを「適切に」実装するには、別の通常のインターフェイス定義を追加するだけでなく、型システムへの深い追加が必要になります。

そのため、インターフェースメカニズムなどを使用する代わりに、独自の型に対するクエリ内包表記を持つ機能が一種のハッキングされています (適切なシグネチャを持つ適切なマジックメソッド名が存在する場合、それらは「魔法のように」機能します)。

于 2009-11-15T04:35:11.223 に答える
-20

モナドは、.NETプログラマーにとって単純に重要ではありません。モナドが存在することさえ知らなくても、LINQフレームワークを構築できます。さらに重要なのは、見た目が変わらないことです。モナド(Haskell)、式ツリーの書き換え(Lisp)、セットベースの操作(SQL)、またはmap / reduceを使用して新しい型(Ruby、Python)を作成するという観点から考えても、最終結果は次のようになります。同じになります。

実際、モナドは.NET開発者にとってまったく役に立たないと言っても過言ではありません。モナドに基づく.NETのライブラリを見るたびに、それは常に、単純なC#またはVBコードよりも冗長で理解しにくいものです。その理由は単純です。C#やVBのような言語は、Haskellのような言語よりもはるかに強力なビルディングブロックに基づいて構築されています。

特にHaskellは、モナドがすべてであるため、すべてにモナドを使用する必要があります。LispのマクロやJavaScriptの動的型付けについても同じことが言えます。あなたがワントリックポニーを持っているとき、そのトリックはかなり良いものでなければなりません。

LINQ、モナド、およびパワーの失明について

于 2009-11-15T06:06:07.330 に答える