Qualcosa di simile MAPM, ma per gli array? (Come arrayMap, ma la mappatura di una funzione impura)

StackOverflow https://stackoverflow.com/questions/1495271

  •  18-09-2019
  •  | 
  •  

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!

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top