Haskell функция отображения на карте (из списка) в новый тип - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь отобразить функцию на экземпляр Map (из Data.Map ), чтобы преобразовать ее в новый тип Map. В частности, у меня есть 2 типа карт:

type Scope = Map.Map String AExpr
type Row = Map.Map String Value

Функция, которая отображает AExpr на Value (с учетом первого аргумента Scope):

evalAExpr :: Scope -> AExpr -> Value

И экземпляр типа Scope, скажем x, для которого я хочу отобразить функцию evalAExpr, чтобы получить экземпляр типа Row.

Согласно документации this должно быть возможно просто используя:

map :: (a -> b) -> Map k a -> Map k b

Так что в моем случае это будет:

x :: Scope
evalAExpr :: Scope -> AExpr -> Value
y = map (evalAExpr x) x :: Row

Так как Scope имеет тип Map String AExpr, а Row имеет тип Map String Value.

Тем не менее, я получаю следующую ошибку:

* 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

Не знаю, почему он настаивает на ожидании списка AExpr вместо Map String AExpr (= Scope). Если бы кто-нибудь мог помочь мне в том, что я делаю неправильно и как go об этом, это было бы очень ценно!

Ответы [ 2 ]

6 голосов
/ 30 января 2020

Вы используете неправильный map.

map, который находится в области действия «по умолчанию» (что означает, что он поступает из автоматически импортируемого модуля Prelude), для списков:

map :: (a -> b) -> [a] -> [b]

Если вы хотите использовать один для Map, вам нужно его импортировать. Вы можете либо скрыть версию списка следующим образом:

import Data.Map (map)

Или, если подход лучше, импортируйте Data.Map как квалифицированный и используйте map с квалификацией:

import qualified Data.Map as M

y = M.map (evalAExpr x) x

В качестве альтернативы, вы можете использовать fmap, который является общей версией map, которая работает для любой структуры данных, которая может быть "отображена". Такие структуры называются «функторами», и Map является одним из них:

y = fmap (evalAExpr x) x

Вы также можете использовать его в форме оператора:

y = evalAExpr x <$> x

Оператор <$> просто псевдоним для fmap.

4 голосов
/ 30 января 2020

map работает только для списков. Используйте fmap (работает для всех функторов) или Map.map.

...