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

时间:2016-12-08 10:04:35

标签: 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 :: 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))

更新2

在@freestyle回答之后,我改变了一点setVar,所以如果你输入一个已经存在的Ident,它会覆盖它。

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

1 个答案:

答案 0 :(得分:3)

我没有看到编译setVar时遇到任何问题,但更好的是setVar (ST xs) i a = ST ((i, a) : xs)

getVar有问题。 filter可以"吃"列表,但您提供了SymTable

所以你可以这样做:

getVar (ST xs) i = snd (head (filter (\x -> fst x == i) xs))

更好的方式:

getVar (ST xs) i = fromJust (lookup i xs)

但是,如果密钥不存在,您将获得异常。所以,也许你想这样:

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