[英]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.