繁体   English   中英

Monadic concatMap for Data.Vector?

[英]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)不太困难-我们可以依赖VectorFunctorMonadTraversable实例。 需要注意的是,您将需要使用常规(未装箱) 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM