Monad实例的数字参数化矢量?

时间:2011-04-27 10:29:35

标签: haskell types monads

Haskell中的静态大小的向量显示在Oleg Kiselyov的Number-parameterized types中,也可以在Hackage上parameterized-data模块的Data.Param.FSVec类型中找到:

data Nat s => FSVec s a

FSVec不是Monad类型类的实例。

列表的monad实例可用于删除或复制元素:

Prelude> [1,2,3] >>= \i -> case i of 1 -> [1,1]; 2 -> []; _ -> [i]
[1,1,3]

是否与列表版本相似,是否可以从固定长度的向量构造monad?

3 个答案:

答案 0 :(得分:7)

是的,如果不是自然的话,这是可能的。

为了满足monad法则,monad必须“对齐”结果。

也就是说,你可以将一个向量看作[0..n-1] -> a的列表函数,然后调整monad实例的函数。

生成的join操作采用矢量向量形式的方阵,并返回其对角线。

给出

tabulate :: Pos n => (forall m. (Nat m, m :<: n) => m -> a) -> FSVec n a

然后

instance Pos n => Monad (FSVec n) where
     return = copy (toNum undefined)
     v >>= f = tabulate (\i -> f (v ! i) ! i)

可悲的是,使用这个monad有些限制。

我的streams包中有六个关于主题的变体,Jeremy Gibbons在这个monad上写了一个blog post

同样,您可以将FSVec n视为representable functor,其代表是以n为界的自然数,然后使用bindReppureRep中的{{1}}定义{3}}包自动获取定义。

答案 1 :(得分:2)

鉴于任何monad都有连接功能,这似乎是不可能的。如果矢量大小不完全为零或一,这将改变矢量大小。不过,你可以把它变成Functor和Applicative。

答案 2 :(得分:-3)

当然可以这样做。只需写下

instance Monad (FSVec s) where
      -- your definition of return
      -- your definition of >>=