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

use*_*349 -1 dictionary haskell types casting map-function

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

type Scope = Map.Map String AExpr
type Row = Map.Map String Value
Run Code Online (Sandbox Code Playgroud)

映射AExprValue(给定它的第一个参数 Scope )的函数:

evalAExpr :: Scope -> AExpr -> Value
Run Code Online (Sandbox Code Playgroud)

还有一个 type 的实例Scope,比如说x,我想为它映射函数evalAExpr以获得一个 type 的实例Row

根据文档,这应该可以简单地使用:

map :: (a -> b) -> Map k a -> Map k b
Run Code Online (Sandbox Code Playgroud)

所以在我的情况下,这将是:

x :: Scope
evalAExpr :: Scope -> AExpr -> Value
y = map (evalAExpr x) x :: Row
Run Code Online (Sandbox Code Playgroud)

由于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
Run Code Online (Sandbox Code Playgroud)

不知道为什么它坚持期望 AExpr 列表而不是Map String AExpr( = Scope)。如果有人可以帮助我解决我做错了什么以及如何解决这个问题,我将不胜感激!

Fyo*_*kin 6

你用错了map

map是在范围上“默认”(这意味着它来自自动导入模块Prelude)可以列出:

map :: (a -> b) -> [a] -> [b]
Run Code Online (Sandbox Code Playgroud)

如果你想使用一个 for Map,你需要导入它。您可以像这样隐藏列表版本:

import Data.Map (map)
Run Code Online (Sandbox Code Playgroud)

或者,一种更好的方法,Data.Map以合格的方式导入,并以合格的方式使用map

import qualified Data.Map as M

y = M.map (evalAExpr x) x
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用fmap,这是map适用于任何可以“映射”的数据结构的通用版本。这种结构称为“函子”,Map是其中之一:

y = fmap (evalAExpr x) x
Run Code Online (Sandbox Code Playgroud)

您还可以以运算符形式使用它:

y = evalAExpr x <$> x
Run Code Online (Sandbox Code Playgroud)

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