Reputation: 879
I'm trying to map a function over a Map (from Data.Map) instance to convert it to a new type of Map. Specifically I've got 2 types of Maps:
type Scope = Map.Map String AExpr
type Row = Map.Map String Value
A function that maps AExpr
to Value
( given its first argument Scope ):
evalAExpr :: Scope -> AExpr -> Value
And an instance of type Scope
, say x
, for which I want to map the function evalAExpr
over to obtain an instance of type Row
.
According to the documentation this should be possible simply using:
map :: (a -> b) -> Map k a -> Map k b
So in my case that would be:
x :: Scope
evalAExpr :: Scope -> AExpr -> Value
y = map (evalAExpr x) x :: Row
Since Scope
has type Map String AExpr
, and Row
has type Map String Value
.
Yet, I'm getting the following error:
* Couldn't match type `Map.Map String AExpr' with `[AExpr]' Expected type: [AExpr] Actual type: Scope * In the second argument of `map', namely `g' In the expression: map (evalAExpr g) g In an equation for r': r' = map (evalAExpr g) g | 43 | r' = map (evalAExpr g) g
No idea why it insists on expecting a list of AExpr instead of a Map String AExpr
( = Scope
). If anyone could help me out on what I'm doing wrong and how to go about this it'd be much appreciated!
Upvotes: 1
Views: 1256
Reputation: 287
map
only works for lists. Use fmap
(works for all functors) or Map.map
.
Upvotes: 4
Reputation: 80765
You're using the wrong map
.
The map
that is in scope "by default" (which means that it comes from auto-imported module Prelude
) is for lists:
map :: (a -> b) -> [a] -> [b]
If you want to use one for Map
, you need to import it. You can either shadow the list version like this:
import Data.Map (map)
Or, a better approach, import Data.Map
as qualified, and use map
with qualification:
import qualified Data.Map as M
y = M.map (evalAExpr x) x
Alternatively, you can use fmap
, which is a general version of map
that works for any data structure that can be "mapped over". Such structures are called "functors", and Map
is one of them:
y = fmap (evalAExpr x) x
You can also use it in operator form:
y = evalAExpr x <$> x
Operator <$>
is just an alias for fmap
.
Upvotes: 7