Haskell 映射函数(fromList)到新类型

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

我正在尝试将函数映射到 Map(来自 Data.Map)实例上,以将其转换为新类型的 Map。具体来说,我有两种类型的地图:

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

AExpr 映射到 Value 的函数(给定其第一个参数 Scope ):

evalAExpr :: Scope -> AExpr -> Value

还有一个 Scope 类型的实例,比如 x,我想为其映射函数 evalAExpr 以获得类型 Row 的实例。

根据 documentation 这应该可以简单地使用:

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 )。如果有人可以帮助我解决我做错了什么以及如何解决这个问题,我们将不胜感激!

你用错了map

范围"by default"中的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 的通用版本,适用于可以是 "mapped over" 的任何数据结构。这样的结构称为"functors",Map就是其中之一:

y = fmap (evalAExpr x) x

您也可以在运算符形式中使用它:

y = evalAExpr x <$> x

运算符 <$> 只是 fmap 的别名。

map 仅适用于列表。使用 fmap(适用于所有函子)或 Map.map.