我自己有两种数据类型,如下所示:
Block a = NoValue | Value a
data GraphAMT a = GraphAMT_ [[Block a]]现在,我想让它们的实例monads像这样
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是否可以成为monad?如果是,那么如何构建它呢?
发布于 2012-11-26 10:37:55
module MatrixOfMatrices where将函数应用于矩阵的元素
data Block a = NoValue | Value a deriving Show
data GraphAMT a = GraphAMT_ [[Block a]] deriving Show首先,你不需要Monad为每个元素添加三个,你需要fmap,所以你应该让你的类型成为函数器的实例,但首先让Block成为函数器将是最简单的:
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无法使用有关其元素的任何事实,因为它们必须适用于所有类型的元素。
没有明确的方法可以做到这一点-您可以通过加宽每一行以容纳传入矩阵的值来将它们放在一起,或者使用转置将它们放在一起。您可以根据矩阵中每个元素所处的位置开始重叠。
https://stackoverflow.com/questions/13537822
复制相似问题