-1

I am very new to Haskell and I wrote a Data Type in Haskell for representing an interval map.

What does that mean? Briefly: A map data type that gives you a value back for every possible key (put simply in my case [0..]).

Then you insert "sequences" like I want my map to hold from 7 to 23 'b' so keys 0 to 6 will be init value e.g. 'a' and 7 to 23 will be 'b' and 24 and ongoing will be 'a' again etc.

I managed to wrote the Data Type, a get and insert function as well as a functor version.

But I can't managed to get a applicative functor version to work. The idea is to set the keys value to [0..] and just work on the values.

Here is my code and thanks for any provided help!

-- Building an interval map data structure in haskell

data IntervalMap k v = IntervalMap {keys :: [k] , values :: [v]} | Empty deriving Show
-- k = key, Typ variable 
-- v = value, Typ variable

singleton :: (Enum k, Num k) => v -> IntervalMap k v
singleton v = IntervalMap{keys=[0..], values= repeat v}

-- get operator => a ! 5 = value at position 5
(!) :: Ord k => IntervalMap k v -> k -> v
(!) iMap k = snd (head (filter (\(x, y) -> x == k) (zip (keys iMap) (values iMap)) ))

-- insert a sequence into intervalMap
insert :: (Ord k, Num k, Enum k) => k -> k -> v -> IntervalMap k v -> IntervalMap k v
insert start end value iMap = IntervalMap {keys=keys iMap, values = rangeChanger (values iMap) start end value}

-- helper function to change a range of values in an intervalMap
rangeChanger :: (Num a1, Enum a1, Ord a1) => [a2] -> a1 -> a1 -> a2 -> [a2]
rangeChanger iMapValues start end value = [if (i >= start) && (i <= end) then newValue else iMapValue | (iMapValue, newValue, i) <- zip3 iMapValues (repeat value) [0..]]


-- functor instance for intervalMap
instance Functor (IntervalMap k) where
    -- fmap :: (a -> b) -> f a -> f b 
    fmap f iMap = IntervalMap {keys=keys iMap, values= map f (values iMap) }


-- applicative functor for intervalMap
instance (Ord k, Num k, Enum k) => Applicative (IntervalMap k) where
pure k = IntervalMap{keys=[0..], values=repeat k}
_ <*> Nothing  = Nothing  
-- HOW TO DO?

-- class Functor functor => Applicative functor where
--  pure :: a -> functor a
--  (<*>) :: functor (a -> b) -> functor a -> functor b
--  (*>) :: functor a -> functor b -> functor b
--  (<*) :: functor a -> functor b -> functor a

jayb
  • 1
  • 2

1 Answers1

3

It seems like you always expect the keys to be [0..], e.g. it is hard-coded in your rangeChanger function. If that is the case then it is redundant and honestly I would leave it out. You can easily reconstruct it by doing something like zip [0..] (values iMap) as you do in the rangeChanger function.

If you make that change, then your IntervalMap data structure is basically the same as ZipList which has an applicative instance here:

instance Applicative ZipList where
    pure x = ZipList (repeat x)
    liftA2 f (ZipList xs) (ZipList ys) = ZipList (zipWith f xs ys)

You see that this doesn't define a <*> but that can be defined in terms of liftA2: p <*> q = liftA2 (\f x -> f x) p q, so you could also write that explicitly for ZipList:

ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)

Edit: I should also mention that one difference with ZipList is that you have an Empty constructor for your IntervalMap type. That makes things harder, you would need to know that your values have some sort of default value, but that is not possible in general (not every type has a default value), so your type cannot be an Applicative. Do you really need that Empty case?

Noughtmare
  • 9,410
  • 1
  • 12
  • 38