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?
答案 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为界的自然数,然后使用bindRep
和pureRep
中的{{1}}定义{3}}包自动获取定义。
答案 1 :(得分:2)
鉴于任何monad都有连接功能,这似乎是不可能的。如果矢量大小不完全为零或一,这将改变矢量大小。不过,你可以把它变成Functor和Applicative。
答案 2 :(得分:-3)
当然可以这样做。只需写下
instance Monad (FSVec s) where
-- your definition of return
-- your definition of >>=