简体   繁体   English

Monadic concatMap for Data.Vector?

[英]Monadic concatMap for Data.Vector?

I'm looking for something from the Data.Vector package which works like concatMap but works with monads. 我正在从Data.Vector包中寻找某些东西,该包的工作方式类似于concatMap但可用于monads。 concatMap has type... concatMap具有类型...

(a -> Vector b) -> Vector a -> Vector b 

but I'm looking for something with type... 但我正在寻找类型...

(Monad m) => (a -> m (Vector b)) -> Vector a -> m (Vector b)

... or, in particular, either one of: ...或特别是以下任何一项:

(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)

The code below should give an idea of what I'm trying to do but produces the error 下面的代码应该给出我要做什么的想法,但是会产生错误

Couldn't match type VU.Vector Int with Int 无法将VU.Vector Int类型与Int匹配
Expected type: m (VU.Vector Int) 期望的类型: m (VU.Vector Int)
Actual type: m (VU.Vector (VU.Vector Int)) 实际类型: m (VU.Vector (VU.Vector Int))
In the expression: return $ VU.concatMap mate mates 在表达式中: 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]

While the mate function in the example does not actually rely on getting a tuple of values, the actual code from which the example is based on does. 尽管示例中的mate函数实际上并不依赖于获取值的元组,但是示例所基于的实际代码却依赖。

Monad m => (a -> m (Vector b)) -> Vector a -> m (Vector b) is not too difficult - we can rely on the Functor , Monad , and Traversable instances of Vector . Monad m => (a -> m (Vector b)) -> Vector a -> m (Vector b)不太困难-我们可以依赖VectorFunctorMonadTraversable实例。 The big caveat is you will need to use a regular (not unboxed) Vector . 需要注意的是,您将需要使用常规(未装箱) 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)

The problem with doing this for unboxed vectors is that in the intermediate fmap fv step I have a Vector (m (Vector b)) and there is no reasonable data instance for that (nor the required corresponding Monad m => Vector Vector (m (Vector b)) class instance). 对于未装箱的矢量执行此操作的问题是,在中间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