1

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
8
  • What code did you try, and what exact error(s) did you actually get? Commented Dec 8, 2016 at 10:15
  • getVar will be partial. After all, it might be that your SymTable doesn't contain the given Ident. You have to wrap Either a [a] in Maybe or similar. Commented Dec 8, 2016 at 10:18
  • List can contain single and many items. Do you really need to use Either? Commented Dec 8, 2016 at 10:19
  • @freestyle Yes, because for me 'a' is a variable and '[a]' is a stack. Commented Dec 8, 2016 at 10:25
  • @Zeta I tried to return Nothing if Ident is not present, but then should I change the header to Maybe Either a [a]? Commented Dec 8, 2016 at 10:26

1 Answer 1

3

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks very much! I've updated the question with a litte modification on setVar
I think you can simplify clearList like this: clearList (x:xs) i | fst x == i = xs (don't continue)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.