Roman Leshchinskiy rl at cse.unsw.edu.au
Thu Apr 1 22:20:23 EDT 2010

```On 02/04/2010, at 13:01, Don Stewart wrote:

> rl:
>> replicate :: Int -> a -> New a
>> replicate n x = Generic.New.unstream (Fusion.Stream.replicate n x)
>>
>> and then either
>>
>>  Mutable.run (replicate n x)
>>
>> to get a mutable vector or
>>
>>  new (replicate n x)
>
>
> Hmm, but here 'a' is pure. I don't think he wants
>
>    newWith :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)
>
> but more:
>
>    newWithM :: (PrimMonad m, MVector v a) => Int -> m a -> m (v (PrimState m) a)

Ah. I missed that. Then your best bet is probably

replicate n action = munstream v \$ Fusion.Stream.Monadic.generateM n (const action)
\$ new n

It's uglier that it should be but vector simply doesn't define the right combinators for this at the moment.

>> to get an immutable one. You could also chain operations on New, including monadic ones:
>>
>>  v <- Mutable.run \$ Generic.New.transform (Fusion.Stream.Monadic.mapM f)
>>                   \$ replicate n x
>>
>
> Oh, that's interesting. But what if we want to fill directly with the monadic action?
> We wouldn't
>
>    mapM (const a) \$ replicate n undefined
>
> So how do we best do a fusible, e.g.:
>
>    replicateM :: G.Vector v a => Int -> IO a -> IO (v a)

There are two things one would have to do. First, add a function to Generic.New which initialises a New from a Monadic.Stream and fusion rules for it. That's easy. The hard part is to generalise New to work with arbitrary monads: at the moment it is defined as:

data New a = New (forall mv s. MVector mv a => ST s (mv s a))

This is because its basic reason for existence is to be passed to Vector.new which then does a runST to produce an immutable vector. It is perhaps possible to make New more general but it's quite tricky. I'll think about it after the ICFP deadline :-)

Roman

```