Algo así como mapm, pero para las matrices? (Como arrayMap, pero el mapeo de una función impuro)

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

  •  18-09-2019
  •  | 
  •  

Pregunta

veo que puedo asignar una función sobre matrices mutables con mapArray, pero no parece ser algo así como mapm (y mapM_). mapArray no me deja imprimir sus elementos, por ejemplo:

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!

El resultado será:

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

¿Hay algo por el estilo en Haskell (o en GHC incluso si no es estándar Haskell)?

Además, he encontrado ninguna función foldr / foldl para las matrices (mutables o no). ¿Existen?

Muchas gracias!

¿Fue útil?

Solución

Tal vez utilizar una de las otras bibliotecas de la matriz, si está haciendo una gran cantidad de mutación? Al igual que uvector?

Si no,

forM_ [1..n] \$ \i ->. unsafeWrite x i 

debería estar bien.

Otros consejos

Importar el módulo Data.Traversable. Se define una clase de tipos de justo lo que desea con las instancias ya definidos para la gama y todo tipo de cosas. Se ha generalizado versiones de secuencia y mapm, además de algunas funciones aún más general de que es probable que no se moleste con mucha frecuencia.

Sólo un simple

import Data.Traversable as T

T.mapM doIOStuff arr

funciona bien.

En el ejemplo de la impresión de todos los elementos:. Puede utilizar "mapM_ print . elems"

Pero parece que desea crear una nueva matriz en donde cada valor es el resultado de una acción monádica de la anterior? En ese 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top