[英]Monadic concatMap for Data.Vector?
我正在从Data.Vector包中寻找某些东西,该包的工作方式类似于concatMap
但可用于monads。 concatMap
具有类型...
(a -> Vector b) -> Vector a -> Vector b
但我正在寻找类型...
(Monad m) => (a -> m (Vector b)) -> Vector a -> m (Vector b)
...或特别是以下任何一项:
(MonadRandom m) => ((Int, Int) -> m (Vector Int))
-> Vector (Int, Int) -> m (Vector Int)
(MonadRandom m) => (Int -> Int -> m (Vector Int))
-> Vector (Int, Int) -> m (Vector Int)
下面的代码应该给出我要做什么的想法,但是会产生错误
无法将
VU.Vector Int
类型与Int
匹配
期望的类型:m (VU.Vector Int)
实际类型:m (VU.Vector (VU.Vector Int))
在表达式中:return $ VU.concatMap mate mates
import Control.Monad
import Control.Monad.Random
import qualified Data.Vector.Unboxed as VU
testReprod :: IO()
testReprod = do
let parents = VU.fromList [1::Int,2,3,4,5,6,7,8,9,10]
children <- reproduce parents
print children
-- concat monadic
reproduce :: (MonadRandom m) => (VU.Vector Int) -> m (VU.Vector Int)
reproduce parents = return $ VU.concatMap mate mates
where
half = VU.length parents `div` 2
mates = VU.zip (VU.take half parents) (VU.drop half parents)
mate :: (MonadRandom m) => (Int, Int) -> m (VU.Vector Int)
mate (a, b) = do
r1 <- getRandomR(0,5)
r2 <- getRandomR(0,5)
return $ VU.fromList [a+r1, b+r2]
尽管示例中的mate
函数实际上并不依赖于获取值的元组,但是示例所基于的实际代码却依赖。
Monad m => (a -> m (Vector b)) -> Vector a -> m (Vector b)
不太困难-我们可以依赖Vector
的Functor
, Monad
和Traversable
实例。 需要注意的是,您将需要使用常规(未装箱) Vector
。
import Data.Vector (Vector)
import Control.Monad (join)
concatMapM :: Monad m => (a -> m (Vector b)) -> Vector a -> m (Vector b)
concatMapM f v = join <$> sequence (fmap f v)
对于未装箱的矢量执行此操作的问题是,在中间fmap fv
步骤中,我有一个Vector (m (Vector b))
并且没有合理的data instance
(也没有所需的对应Monad m => Vector Vector (m (Vector b))
类实例)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.