summaryrefslogtreecommitdiff
path: root/testsuite/tests/indexed-types/should_run/GMapTop.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/indexed-types/should_run/GMapTop.hs')
-rw-r--r--testsuite/tests/indexed-types/should_run/GMapTop.hs69
1 files changed, 69 insertions, 0 deletions
diff --git a/testsuite/tests/indexed-types/should_run/GMapTop.hs b/testsuite/tests/indexed-types/should_run/GMapTop.hs
new file mode 100644
index 0000000000..9ce830950b
--- /dev/null
+++ b/testsuite/tests/indexed-types/should_run/GMapTop.hs
@@ -0,0 +1,69 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module Main where
+
+import Prelude hiding (lookup)
+import Data.Char (ord)
+import qualified Data.Map as Map
+
+
+-- Generic maps as toplevel indexed data types
+----------------------------------------------
+
+data family GMap k :: * -> *
+data instance GMap Int v = GMapInt (Map.Map Int v)
+data instance GMap Char v = GMapChar (GMap Int v)
+data instance GMap () v = GMapUnit (Maybe v)
+data instance GMap (a, b) v = GMapPair (GMap a (GMap b v))
+data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)
+
+class GMapKey k where
+ empty :: GMap k v
+ lookup :: k -> GMap k v -> Maybe v
+ insert :: k -> v -> GMap k v -> GMap k v
+
+instance GMapKey Int where
+ empty = GMapInt Map.empty
+ lookup k (GMapInt m) = Map.lookup k m
+ insert k v (GMapInt m) = GMapInt (Map.insert k v m)
+
+instance GMapKey Char where
+ empty = GMapChar empty
+ lookup k (GMapChar m) = lookup (ord k) m
+ insert k v (GMapChar m) = GMapChar (insert (ord k) v m)
+
+instance GMapKey () where
+ empty = GMapUnit Nothing
+ lookup () (GMapUnit v) = v
+ insert () v (GMapUnit _) = GMapUnit $ Just v
+
+instance (GMapKey a, GMapKey b) => GMapKey (a, b) where
+ empty = GMapPair empty
+ lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b
+ insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of
+ Nothing -> insert a (insert b v empty) gm
+ Just gm2 -> insert a (insert b v gm2 ) gm
+
+instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where
+ empty = GMapEither empty empty
+ lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1
+ lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2
+ insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2
+ insert (Right a) v (GMapEither gm1 gm2) = GMapEither gm1 (insert a v gm2)
+
+
+-- Test code
+-- ---------
+
+nonsence :: GMap Bool String
+nonsence = undefined
+
+myGMap :: GMap (Int, Either Char ()) String
+myGMap = insert (5, Left 'c') "(5, Left 'c')" $
+ insert (4, Right ()) "(4, Right ())" $
+ insert (5, Right ()) "This is the one!" $
+ insert (5, Right ()) "This is the two!" $
+ insert (6, Right ()) "(6, Right ())" $
+ insert (5, Left 'a') "(5, Left 'a')" $
+ empty
+main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap