簡體   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