List 创建用于在Haskell中存储数据的表
我试图在Haskell中以键值样式存储数据。我的想法是,我有一个标识(Ident),它可以是单个值或它们的列表 我尝试了以下结构: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
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
(不要继续)