user2999349
user2999349

Reputation: 879

Haskell map function over a map (fromList) to new type

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

Answers (2)

Gabscap
Gabscap

Reputation: 287

map only works for lists. Use fmap (works for all functors) or Map.map.

Upvotes: 4

Fyodor Soikin
Fyodor Soikin

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

Related Questions