Difference between revisions of "The Monad.Reader/Discuss Issue11"

From HaskellWiki
Jump to navigation Jump to search
m
m (Move code to its own page.)
Line 1: Line 1:
 
=== How to Refold a Map ===
 
=== How to Refold a Map ===
   
A reader (roconner on the www.reddit.com website) pointed out that Incremental Map might be better implemented with FingerTrees. I was unfamiliar with FingerTrees, but very pleased with what I found. Indeed, it is easy to directly implement Incremental Maps with FingerTrees. I've attached a sketch of the implementation to serve as a follow-up to my article.
+
A reader (roconner on the www.reddit.com website) pointed out that Incremental Map might be better implemented with FingerTrees. I was unfamiliar with FingerTrees, but very pleased with what I found. Indeed, it is easy to directly implement Incremental Maps with FingerTrees. I've attached a [[The_Monad.Reader/Discuss_Issue11/FingerTreeIMap|sketch]] of the implementation to serve as a follow-up to my article.
   
 
--[[User:Dfplace|Dfplace]] 16:04, 12 September 2008 (UTC)
 
--[[User:Dfplace|Dfplace]] 16:04, 12 September 2008 (UTC)
 
<haskell>
 
{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances #-}
 
module IMap where
 
import Data.FingerTree hiding (fromList)
 
import Data.List hiding (insert,delete,lookup)
 
import Prelude hiding (lookup)
 
import Data.Monoid
 
import Data.Function
 
 
data Elem a b = Elem a b
 
 
data Key k v = NoKey | Key k v
 
 
instance Eq k => Eq (Key k v) where
 
(Key j _) == (Key k _) = j == k
 
 
instance Ord k => Ord (Key k v) where
 
compare (Key j _) (Key k _) = compare j k
 
 
instance Monoid v => Monoid (Key a v) where
 
mempty = NoKey
 
k `mappend` NoKey = k
 
NoKey `mappend` k = k
 
(Key _ x) `mappend` (Key k y) = Key k (x `mappend` y)
 
 
data IMap a b = IMap (FingerTree (Key a b) (Elem a b))
 
 
instance (Monoid b) => Measured (Key a b) (Elem a b) where
 
measure (Elem x y) = Key x y
 
 
insert :: (Ord k, Monoid v) => k -> v -> IMap k v -> IMap k v
 
insert k v inp@(IMap xs) = insert' $ viewl r
 
where
 
(l,r) = split (>= Key k undefined) xs
 
new = IMap ( l >< (Elem k v <| r))
 
insert' ((Elem y _) :< r')
 
| k == y = IMap ( l >< (Elem k v <| r'))
 
| otherwise = new
 
insert' EmptyL = new
 
 
delete :: (Ord k, Monoid v) => k -> IMap k v -> IMap k v
 
delete x (IMap xs) = IMap (l >< r')
 
where
 
(l,r) = split (>= Key x undefined) xs
 
(_,r') = split (> Key x undefined) r
 
 
lookup :: (Monad m, Ord t, Monoid v) => t -> IMap t v -> m v
 
lookup x (IMap xs) = lookup' $
 
viewl . snd $
 
split (>= Key x undefined) xs
 
where
 
lookup' ((Elem y v) :< _)
 
| y == x = return v
 
| otherwise = fail "IMap.lookup failed"
 
lookup' EmptyL = fail "IMap.lookup failed"
 
 
getValue :: (Monoid v) => IMap k v -> v
 
getValue (IMap xs) = let (Key _ v) = measure xs in v
 
</haskell>
 

Revision as of 16:18, 12 September 2008

How to Refold a Map

A reader (roconner on the www.reddit.com website) pointed out that Incremental Map might be better implemented with FingerTrees. I was unfamiliar with FingerTrees, but very pleased with what I found. Indeed, it is easy to directly implement Incremental Maps with FingerTrees. I've attached a sketch of the implementation to serve as a follow-up to my article.

--Dfplace 16:04, 12 September 2008 (UTC)