Qualcosa di simile MAPM, ma per gli array? (Come arrayMap, ma la mappatura di una funzione impura)
Domanda
vedo che posso tracciare una funzione più di array mutevoli con mapArray, ma ci non sembra essere qualcosa di simile MAPM (e mapM_). mapArray non mi permette di stampare i suoi elementi, ad esempio:
import Data.Array.Storable
arr <- newArray (1,10) 42 :: IO -- answer to Life, Universe and Everything
x <- readLn :: IO Int
mapArray (putStrLn.show) arr -- <== this doesn't work!
Il risultato sarà:
No instances for (MArray StorableArray Int m,
MArray StorableArray (IO ()) m)
arising from a use of `mapArray' at <interactive>:1:0-27
Possible fix:
add an instance declaration for
(MArray StorableArray Int m, MArray StorableArray (IO ()) m)
In the expression: mapArray (putStrLn . show) arr
In the definition of `it': it = mapArray (putStrLn . show) arr
C'è qualcosa di simile in Haskell (o in GHC anche se non di serie Haskell)?
Inoltre, ho trovato nessuna funzione foldr / foldl per gli array (mutabili e non). Esistono?
Grazie mille!
Soluzione
Forse utilizzare una delle altre librerie di array, se si sta facendo un sacco di mutazione? Come uvector?
In caso contrario,
forM_ [1..n] \$ \i ->. unsafeWrite x i
dovrebbe andare bene.
Altri suggerimenti
Importare il modulo Data.Traversable. Si definisce un typeclass solo per ciò che si vuole con le istanze già definite per serie e ogni genere di cose. Si è generalizzata versioni di sequenza e MAPM, più alcune funzioni ancora più generale che probabilmente non darà fastidio con molto spesso.
Basta un semplice
import Data.Traversable as T
T.mapM doIOStuff arr
funziona bene.
Per l'esempio di stampa di tutti gli elementi:. È possibile utilizzare "mapM_ print . elems
"
Ma sembra che si desidera creare un nuovo array in cui ogni valore è il risultato di un'azione monadica di quello precedente? In tal caso:
arrayMapM :: (Monad m, Ix i) => (a -> m b) -> Array i a -> m (Array i b)
arrayMapM func src =
liftM (listArray (bounds src)) . mapM func . elems $ src