Re: [Haskell-beginners] Signature of monadic functions

I think I am looking at the problem in a wrong way... What I want to do is using higher-order functions with IO (or an IO-based transformer). For example, let's say I want to apply a function to all the keys in a Map. With pure functions, I would do: Map.mapKeys doSomething myMap But let's suppose the function has a signature: doSomething :: a -> IO b Is there an easy way to apply it?

Hi,
Map.mapKeys has constraint (Ord k2) and IO a does not provide instance of Ord.
One way to make a way around this, I can come up with is :
import Data.Map
test_a :: Map Int Int
test_a = fromList [ (i, i) | i <- [1..10] ]
print_a :: Int -> IO Int
print_a a = ( putStrLn.show $ a ) >> return a
test_b :: IO (Map Int Int)
test_b = fmap fromList $ mapM (\ (a, b) -> (do
t <- print_a a
return (t, b) )) $ toList test_a
Thanks
Divyanshu Ranjan
On Thu, Oct 17, 2013 at 2:43 PM, Lorenzo Tabacchini
I think I am looking at the problem in a wrong way...
What I want to do is using higher-order functions with IO (or an IO-based transformer).
For example, let's say I want to apply a function to all the keys in a Map. With pure functions, I would do: Map.mapKeys doSomething myMap
But let's suppose the function has a signature: doSomething :: a -> IO b
Is there an easy way to apply it? _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Hi Lorenzo, all the nice abstractions like Functor, Traversable or Foldable operate on the values of the Map. So there's 'Data.Traversable.mapM', which almost does what you want, but only for the values of the Map. Ok, here's a solution that does what you want: import Data.Map import Control.Monad mapKeysM :: (Ord k1, Ord k2, Monad m) => (k1 -> m k2) -> Map k1 v -> m (Map k2 v) mapKeysM f map = return . fromList =<< mapM g (toList map) where g (key, value) = do key' <- f key return (key', value) Certainly there has to be a solution using the lens library ... Greetings, Daniel

Le 17 oct. 2013 12:57, "Daniel Trstenjak"
Hi Lorenzo,
all the nice abstractions like Functor, Traversable or Foldable operate on the values of the Map. So there's 'Data.Traversable.mapM', which almost does what you want, but only for the values of the Map.
Ok, here's a solution that does what you want:
import Data.Map import Control.Monad
mapKeysM :: (Ord k1, Ord k2, Monad m) => (k1 -> m k2) -> Map k1 v -> m
(Map k2 v)
mapKeysM f map = return . fromList =<< mapM g (toList map) where g (key, value) = do key' <- f key return (key', value)
If you're worried that constructing the whole list then consuming it is too much (use of mapM precludes a good streaming), you could use foldM to construct the Map immediately, which would probably be exactly equivalent to what mapKeys has to be doing (changing the keys obviously means rebuilding the Map from scratch). -- Chaddaï
participants (4)
-
Chaddaï Fouché
-
Daniel Trstenjak
-
divyanshu ranjan
-
Lorenzo Tabacchini