List 创建用于在Haskell中存储数据的表

List 创建用于在Haskell中存储数据的表,list,haskell,data-structures,key-value,List,Haskell,Data Structures,Key Value,我试图在Haskell中以键值样式存储数据。我的想法是,我有一个标识(Ident),它可以是单个值或它们的列表 我尝试了以下结构: type Ident = String data SymTable a = ST [(Ident, Either a [a])] deriving (Show) setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a getVar :: SymTa

我试图在Haskell中以键值样式存储数据。我的想法是,我有一个标识(Ident),它可以是单个值或它们的列表

我尝试了以下结构:

type Ident = String
data SymTable a = ST [(Ident, Either a [a])]
                  deriving (Show)
setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
getVar :: SymTable a -> Ident -> Either a [a]
当我试图定义以下基本函数来存储/检索数据结构中的数据时,就会出现问题:

type Ident = String
data SymTable a = ST [(Ident, Either a [a])]
                  deriving (Show)
setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
getVar :: SymTable a -> Ident -> Either a [a]
我已经尝试了几个实现,但无法让编译器工作(接受类型)

作为约束,我不能使用任何外部库(没有映射或类似)

更新

所以我的想法是这样做:

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
setVar (ST xs) i a = ST ([(i, a)] ++ xs)

getVar :: SymTable a -> Ident -> Either a [a]
getVar t i = snd (head (filter (\x -> fst x == i) t))
getVar (ST xs) i = snd (head (filter (\x -> fst x == i) xs))
getVar :: SymTable a -> Ident -> Maybe (Either a [a])
getVar (ST xs) i = lookup i xs
更新2

在@freestyle answer之后,我修改了一点setVar,所以如果您输入一个已经存在的标识,它会覆盖它

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
setVar (ST xs) i a = ST ([(i, a)] ++ clearList xs i)
   where
       clearList [] _ = []
       clearList (x:xs) i
           | fst x == i = clearList xs i
           | otherwise = x : clearList xs i
getVar仍然按照他的建议:

getVar :: SymTable a -> Ident -> Maybe (Either a [a])
getVar (ST xs) i = lookup i xs

我认为编译
setVar
没有任何问题,但更好的是
setVar(stxs)ia=ST((I,a):xs)

您对
getVar
有问题。
过滤器
可以“吃掉”列表,但您给出了
符号表

所以你可以这样做:

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
setVar (ST xs) i a = ST ([(i, a)] ++ xs)

getVar :: SymTable a -> Ident -> Either a [a]
getVar t i = snd (head (filter (\x -> fst x == i) t))
getVar (ST xs) i = snd (head (filter (\x -> fst x == i) xs))
getVar :: SymTable a -> Ident -> Maybe (Either a [a])
getVar (ST xs) i = lookup i xs
更好的方法:

getVar (ST xs) i = fromJust (lookup i xs)
但是,如果密钥不存在,您将得到一个异常。所以,也许你想要这样:

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
setVar (ST xs) i a = ST ([(i, a)] ++ xs)

getVar :: SymTable a -> Ident -> Either a [a]
getVar t i = snd (head (filter (\x -> fst x == i) t))
getVar (ST xs) i = snd (head (filter (\x -> fst x == i) xs))
getVar :: SymTable a -> Ident -> Maybe (Either a [a])
getVar (ST xs) i = lookup i xs

我认为编译
setVar
没有任何问题,但更好的是
setVar(stxs)ia=ST((I,a):xs)

您对
getVar
有问题。
过滤器
可以“吃掉”列表,但您给出了
符号表

所以你可以这样做:

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
setVar (ST xs) i a = ST ([(i, a)] ++ xs)

getVar :: SymTable a -> Ident -> Either a [a]
getVar t i = snd (head (filter (\x -> fst x == i) t))
getVar (ST xs) i = snd (head (filter (\x -> fst x == i) xs))
getVar :: SymTable a -> Ident -> Maybe (Either a [a])
getVar (ST xs) i = lookup i xs
更好的方法:

getVar (ST xs) i = fromJust (lookup i xs)
但是,如果密钥不存在,您将得到一个异常。所以,也许你想要这样:

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
setVar (ST xs) i a = ST ([(i, a)] ++ xs)

getVar :: SymTable a -> Ident -> Either a [a]
getVar t i = snd (head (filter (\x -> fst x == i) t))
getVar (ST xs) i = snd (head (filter (\x -> fst x == i) xs))
getVar :: SymTable a -> Ident -> Maybe (Either a [a])
getVar (ST xs) i = lookup i xs

您尝试了什么代码?您实际得到了什么准确的错误?
getVar
将是部分错误。毕竟,可能是您的
SymTable
不包含给定的
Ident
。您必须在
中包装[a]
或类似内容。列表可以包含单个或多个项目。你真的需要使用
或者
?@freestyle是的,因为对我来说'a'是一个变量,'[a]'是一个堆栈。@Zeta如果Ident不存在,我尝试不返回任何内容,但是我应该将标题更改为a[a]?你尝试了什么代码,你实际得到了什么准确的错误?
getVar
将是部分的。毕竟,可能是您的
SymTable
不包含给定的
Ident
。您必须在
中包装[a]
或类似内容。列表可以包含单个或多个项目。你真的需要使用
吗?@freestyle是的,因为对我来说'a'是一个变量,'[a]'是一个堆栈。@Zeta如果Ident不存在,我试图不返回任何内容,但是我是否应该将标题更改为a[a]?非常感谢!我在setVarI上做了一些修改,更新了这个问题。我想你可以这样简化
clearList
clearList(x:xs)I | fst x==I=xs
(不要继续)非常感谢!我在setVarI上做了一些修改,更新了这个问题。我想你可以简化
clearList
如下:
clearList(x:xs)I | fst x==I=xs
(不要继续)