首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >构建嵌套Monad

构建嵌套Monad
EN

Stack Overflow用户
提问于 2012-11-24 10:53:11
回答 1查看 433关注 0票数 2

我自己有两种数据类型,如下所示:

代码语言:javascript
复制
Block a = NoValue | Value a
data GraphAMT a = GraphAMT_ [[Block a]]

现在,我想让它们的实例monads像这样

代码语言:javascript
复制
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?如果是,那么如何构建它呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-26 10:37:55

代码语言:javascript
复制
module MatrixOfMatrices where

将函数应用于矩阵的元素

代码语言:javascript
复制
data Block a = NoValue | Value a  deriving Show
data GraphAMT a = GraphAMT_ [[Block a]]  deriving Show

首先,你不需要Monad为每个元素添加三个,你需要fmap,所以你应该让你的类型成为函数器的实例,但首先让Block成为函数器将是最简单的:

代码语言:javascript
复制
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

什么时候

代码语言:javascript
复制
testData = GraphAMT_ [[NoValue,Value 2],[Value 56,Value 45,NoValue],[NoValue]]

然后

代码语言:javascript
复制
*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无法使用有关其元素的任何事实,因为它们必须适用于所有类型的元素。

没有明确的方法可以做到这一点-您可以通过加宽每一行以容纳传入矩阵的值来将它们放在一起,或者使用转置将它们放在一起。您可以根据矩阵中每个元素所处的位置开始重叠。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13537822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档