user4316384
user4316384

Reputation:

Creating a table for storing data in Haskell

I'm trying to store data in a key-value style in Haskell. The idea is that I have an identification (Ident) and it can be a single value or a list of them.

I have tried the following structure:

type Ident = String
data SymTable a = ST [(Ident, Either a [a])]
                  deriving (Show)

The problem comes when I try to define the following basic functions to store/retrieve data from the data structure:

setVar :: SymTable a -> Ident -> Either a [a] -> SymTable a
getVar :: SymTable a -> Ident -> Either a [a]

I've tried several implementations but I can't get the compiler to work (accept types).

As a constraint, I can't use any external library (no Map or similars).

UPDATE

So my idea was to do something like this:

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))

UPDATE 2

Following @freestyle answer, i changed a little bit setVar so if you input an Ident that already exists, it overwrites it.

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 stays as he suggested:

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

Upvotes: 1

Views: 2124

Answers (1)

freestyle
freestyle

Reputation: 3790

I don't see any problem with compilation of setVar, but more better is setVar (ST xs) i a = ST ((i, a) : xs).

You have problem with getVar. The filter can "eat" a list, but you gave the SymTable.

So you can do like this:

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

More better way:

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

But, if key doesn't exist you will get an exception. So, maybe you want like this:

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

Upvotes: 3

Related Questions