module MatrixOfMatrices where
将函数应用于矩阵的元素
data Block a = NoValue | Value a deriving Show
data GraphAMT a = GraphAMT_ [[Block a]] deriving Show
首先,你不需要 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]]
如你所愿。
将矩阵变成 Monad
哎呀!我们需要定义(>>=) :: GraphAMT a -> (a -> GraphAMT b) -> GraphAMT b
. 它应该采用一个将元素转换为矩阵的函数,按元素应用它,然后将生成的矩阵矩阵连接到一个矩阵中。
这样做的问题是没有明显的方法可以将矩阵矩阵变成单个矩阵,就像列表列表变成列表一样。如果元素都是数字,我们可以把它们加在一起,形成一个最大尺寸的矩阵。但是我们不能使用这样的解决方案,因为 Monad 无法使用有关其元素的任何事实,因为它们必须适用于所有类型的元素。
没有明确的方法可以做到这一点 - 您可以通过加宽每一行以容纳传入矩阵的值将它们彼此相邻,或者使用转置将它们放在彼此下方。您可以根据每个矩阵在矩阵中的位置开始重叠。