2

私は次のように2つの独自のデータ型を持っています:

Block a = NoValue | Value a
data GraphAMT a = GraphAMT_ [[Block a]]

今、私はそれらのためにインスタンスモナドを作りたいです

instance Monad Block where
     return a = Value a
     NoValue >>= f = NoValue
     Value a >>= f = f a
     fail _ = NoValue

instance Monad GraphAMT where
     return a = GraphAMT_ [[Value a]]
     GraphAMT_ xs >>= f = ...?

GraphAMT がモナドになれるかどうか疑問に思っていますか? はいの場合、それを構築する方法は?

4

1 に答える 1

3
module MatrixOfMatrices where

行列の要素に関数を適用する

data Block a = NoValue | Value a  deriving Show
data GraphAMT a = GraphAMT_ [[Block a]]  deriving Show

まず、各要素に 3 を追加するのに Monad は必要ありません。必要なfmapので、型を Functor のインスタンスにする必要がありますが、Block最初に Functor を作成するのが最も簡単です。

instance Functor Block where
  fmap f NoValue  = NoValue
  fmap f (Value a) = Value (f a)

instance Functor GraphAMT where
 fmap f (GraphAMT_ xss) = GraphAMT_ . (map . map . fmap $ f) $ xss

いつ

testData = GraphAMT_ [[NoValue,Value 2],[Value 56,Value 45,NoValue],[NoValue]]

それから

*MatrixOfMatrices> testData
GraphAMT_ [[NoValue,Value 2],[Value 56,Value 45,NoValue],[NoValue]]
*MatrixOfMatrices> fmap (*10) testData
GraphAMT_ [[NoValue,Value 20],[Value 560,Value 450,NoValue],[NoValue]]

あなたが望むように。

行列をモナドにする

うわぁ!を定義する必要があります(>>=) :: GraphAMT a -> (a -> GraphAMT b) -> GraphAMT b。要素を行列に変換する関数を取り、それを要素ごとに適用し、結果の行列の行列を 1 つの行列に結合する必要があります。

それに関する問題は、リストのリストがリストになるように、マトリックスのマトリックスを単一のマトリックスにする明確な方法がないことです。要素がすべて数値の場合、それらを足し合わせて最大サイズの行列を作成できます。ただし、モナドはすべてのタイプの要素に対して機能する必要があるため、要素に関する事実を使用できないため、そのようなソリューションを使用することはできません。

これを行う明確な方法はありません。入力行列の値を収容するために各行を広げてそれらを隣り合わせにするか、転置を使用してそれらを互いの下に配置することができます。それぞれがあったマトリックスのマトリックス内の位置に従って、オーバーラップを開始できます。

于 2012-11-26T02:37:55.197 に答える