Map
authorJulien Moutinho <julm+symantic@autogeree.net>
Fri, 11 Nov 2016 22:19:32 +0000 (23:19 +0100)
committerJulien Moutinho <julm+symantic@autogeree.net>
Fri, 11 Nov 2016 22:19:32 +0000 (23:19 +0100)
44 files changed:
Language/Symantic/AST/Test.hs
Language/Symantic/Expr/Applicative.hs
Language/Symantic/Expr/Applicative/Test.hs
Language/Symantic/Expr/Bool/Test.hs
Language/Symantic/Expr/Eq/Test.hs
Language/Symantic/Expr/Foldable.hs
Language/Symantic/Expr/Foldable/Test.hs
Language/Symantic/Expr/Functor.hs
Language/Symantic/Expr/Functor/Test.hs
Language/Symantic/Expr/If/Test.hs
Language/Symantic/Expr/Int/Test.hs
Language/Symantic/Expr/Lambda/Test.hs
Language/Symantic/Expr/List.hs
Language/Symantic/Expr/List/Test.hs
Language/Symantic/Expr/Map.hs
Language/Symantic/Expr/Map/HLint.hs [new symlink]
Language/Symantic/Expr/Map/Test.hs [new file with mode: 0644]
Language/Symantic/Expr/Maybe.hs
Language/Symantic/Expr/Maybe/Test.hs
Language/Symantic/Expr/Monad.hs
Language/Symantic/Expr/Monad/Test.hs
Language/Symantic/Expr/Test.hs
Language/Symantic/Expr/Traversable.hs
Language/Symantic/Expr/Traversable/Test.hs
Language/Symantic/Expr/Tuple.hs
Language/Symantic/Repr/Dup.hs
Language/Symantic/Repr/Host.hs
Language/Symantic/Repr/Host/Test.hs
Language/Symantic/Repr/Text.hs
Language/Symantic/Repr/Text/Test.hs
Language/Symantic/Type/Bool.hs
Language/Symantic/Type/Either.hs
Language/Symantic/Type/Fun.hs
Language/Symantic/Type/Int.hs
Language/Symantic/Type/Map.hs
Language/Symantic/Type/Maybe.hs
Language/Symantic/Type/Ordering.hs
Language/Symantic/Type/Text.hs
Language/Symantic/Type/Tuple.hs
Language/Symantic/Type/Type0.hs
Language/Symantic/Type/Type1.hs
Language/Symantic/Type/Type2.hs
Language/Symantic/Type/Unit.hs
symantic.cabal

index 4007efc3276efd3a1dc8965c2a2a17f27e782674..a0d482600c65fad05dc306fc1db04f6e88a46308 100644 (file)
@@ -48,12 +48,27 @@ instance Show AST where
                                showsPrec prec_arrow a .
                                showString (" "++n++" ") .
                                showsPrec prec_arrow b
+                AST "\\" [var, ty, body] ->
+                               showParen (p >= prec_lambda) $
+                               showString ("\\(") .
+                               showsPrec prec_lambda var .
+                               showString (":") .
+                               showsPrec prec_lambda ty .
+                               showString (") -> ") .
+                               showsPrec prec_lambda body
+                AST "$" [fun, arg] ->
+                               showParen (p >= prec_app) $
+                               showsPrec prec_app fun .
+                               showString (" $ ") .
+                               showsPrec prec_app arg
                 _ ->
                        showString n .
                        showString "(" .
                        showString (List.intercalate ", " $ show Prelude.<$> args) .
                        showString ")"
-               where prec_arrow = 1
+               where prec_arrow  = 1
+                     prec_lambda = 1
+                     prec_app    = 1
 
 -- ** Parsing utilities
 from_ast0
@@ -217,6 +232,19 @@ instance -- Type_from AST Type_Int
                         _ -> Left $ lift_error_type $
                                Error_Type_Wrong_number_of_arguments ast 0
                 _ -> Left $ error_type_unsupported ty ast
+instance -- Type_from AST Type_Text
+ ( Lift_Type_Root Type_Text root
+ , Lift_Error_Type (Error_Type AST) (Error_of_Type AST root)
+ , IBool (Is_Last_Type (Type_Text root) root)
+ ) => Type_from AST (Type_Text root) where
+       type_from ty ast k =
+               case ast of
+                AST "Text" asts ->
+                       case asts of
+                        [] -> k type_text
+                        _ -> Left $ lift_error_type $
+                               Error_Type_Wrong_number_of_arguments ast 0
+                _ -> Left $ error_type_unsupported ty ast
 instance -- Type_from AST Type_Ordering
  ( Lift_Type_Root Type_Ordering root
  , Lift_Error_Type (Error_Type AST) (Error_of_Type AST root)
@@ -302,7 +330,6 @@ instance -- Type_from AST Type_Map
                         [ast_k, ast_a] ->
                                type_from (Proxy::Proxy root) ast_k $ \ty_k ->
                                type_from (Proxy::Proxy root) ast_a $ \ty_a ->
-                               check_type_constraint (Proxy::Proxy Ord) ast_k ty_k $ \Dict ->
                                k (type_map ty_k ty_a)
                         _ -> Left $ lift_error_type $
                                Error_Type_Wrong_number_of_arguments ast 2
@@ -524,6 +551,24 @@ instance -- Expr_from AST Expr_Int
                 AST "*"      asts -> op2_from_AST (Expr.*)    type_int asts ex ast
                 AST "mod"    asts -> op2_from_AST Expr.mod    type_int asts ex ast
                 _ -> \_ctx _k -> Left $ error_expr_unsupported ex ast
+instance -- Expr_from AST Expr_Text
+ ( Eq_Type (Type_Root_of_Expr root)
+ , Expr_from AST root
+ , Lift_Type_Root Type_Text (Type_Root_of_Expr root)
+ , Lift_Error_Expr (Error_Expr_of_Root AST root) (Error_of_Expr AST root)
+ , Unlift_Type Type_Text (Type_of_Expr root)
+ , Root_of_Expr root ~ root
+ , IBool (Is_Last_Expr (Expr_Text root) root)
+ ) => Expr_from AST (Expr_Text root) where
+       expr_from ex ast =
+               case ast of
+                AST "text" asts ->
+                       case asts of
+                        [AST lit []] -> \_ctx k ->
+                               k type_text $ Forall_Repr_with_Context $ \_c -> text lit
+                        _ -> \_ctx _k -> Left $ error_expr ex $
+                               Error_Expr_Wrong_number_of_arguments ast 1
+                _ -> \_ctx _k -> Left $ error_expr_unsupported ex ast
 instance -- Expr_from AST Expr_Lambda
  ( Eq_Type (Type_Root_of_Expr root)
  , Type_from AST (Type_Root_of_Expr root)
@@ -626,18 +671,24 @@ instance -- Expr_from AST Expr_List
                         ast_ty_a:asts' -> list_from ast_ty_a asts' ex ast ctx k
                         _ -> Left $ error_expr ex $
                                Error_Expr_Wrong_number_of_arguments ast 1
+                AST "list_zipWith" asts -> from_ast3 asts list_zipWith_from ex ast ctx k
+                AST "list_reverse" asts -> from_ast1 asts list_reverse_from ex ast ctx k
                 _ -> Left $ error_expr_unsupported ex ast
 instance -- Expr_from AST Expr_Map
  ( Eq_Type (Type_Root_of_Expr root)
  , Expr_from AST root
- , Lift_Type   Type_Fun (Type_of_Expr root)
- , Unlift_Type Type_Fun (Type_of_Expr root)
- , Lift_Type   Type_Map       (Type_of_Expr root)
- , Unlift_Type Type_Map       (Type_of_Expr root)
- , Lift_Type   Type_List      (Type_of_Expr root)
- , Unlift_Type Type_List      (Type_of_Expr root)
- , Lift_Type   Type_Tuple2    (Type_of_Expr root)
- , Unlift_Type Type_Tuple2    (Type_of_Expr root)
+ , Lift_Type   Type_Fun    (Type_of_Expr root)
+ , Unlift_Type Type_Fun    (Type_of_Expr root)
+ , Lift_Type   Type_Bool   (Type_of_Expr root)
+ , Unlift_Type Type_Bool   (Type_of_Expr root)
+ , Lift_Type   Type_List   (Type_of_Expr root)
+ , Unlift_Type Type_List   (Type_of_Expr root)
+ , Lift_Type   Type_Map    (Type_of_Expr root)
+ , Unlift_Type Type_Map    (Type_of_Expr root)
+ , Lift_Type   Type_Maybe  (Type_of_Expr root)
+ , Unlift_Type Type_Maybe  (Type_of_Expr root)
+ , Lift_Type   Type_Tuple2 (Type_of_Expr root)
+ , Unlift_Type Type_Tuple2 (Type_of_Expr root)
  , Constraint_Type Ord (Type_Root_of_Expr root)
  , Lift_Error_Expr (Error_Expr_of_Root AST root) (Error_of_Expr AST root)
  , Root_of_Expr root ~ root
@@ -645,8 +696,15 @@ instance -- Expr_from AST Expr_Map
  ) => Expr_from AST (Expr_Map root) where
        expr_from ex ast ctx k =
                case ast of
-                AST "map_from_list" asts -> from_ast1 asts map_from_list_from ex ast ctx k
-                AST "mapWithKey"    asts -> from_ast2 asts mapWithKey_from ex ast ctx k
+                AST "map_from_list"    asts -> from_ast1 asts map_from_list_from ex ast ctx k
+                AST "mapWithKey"       asts -> from_ast2 asts mapWithKey_from ex ast ctx k
+                AST "map_lookup"       asts -> from_ast2 asts map_lookup_from ex ast ctx k
+                AST "map_keys"         asts -> from_ast1 asts map_keys_from ex ast ctx k
+                AST "map_member"       asts -> from_ast2 asts map_member_from ex ast ctx k
+                AST "map_insert"       asts -> from_ast3 asts map_insert_from ex ast ctx k
+                AST "map_delete"       asts -> from_ast2 asts map_delete_from ex ast ctx k
+                AST "map_difference"   asts -> from_ast2 asts map_difference_from ex ast ctx k
+                AST "map_foldrWithKey" asts -> from_ast3 asts map_foldrWithKey_from ex ast ctx k
                 _ -> Left $ error_expr_unsupported ex ast
 instance -- Expr_from AST Expr_Functor
  ( Eq_Type (Type_Root_of_Expr root)
@@ -743,6 +801,7 @@ instance -- Expr_from AST Expr_Monoid
                case ast of
                 AST "mempty"  asts -> from_ast1 asts mempty_from ex ast ctx k
                 AST "mappend" asts -> from_ast2 asts mappend_from ex ast ctx k
+                AST "<>"      asts -> from_ast2 asts mappend_from ex ast ctx k
                 _ -> Left $ error_expr_unsupported ex ast
 instance -- Expr_from AST Expr_Monad
  ( Eq_Type (Type_Root_of_Expr root)
@@ -777,3 +836,18 @@ instance -- Expr_from AST Expr_Either
                 AST "left"  asts -> from_ast2 asts left_from  ex ast ctx k
                 AST "right" asts -> from_ast2 asts right_from ex ast ctx k
                 _ -> Left $ error_expr_unsupported ex ast
+instance -- Expr_from AST Expr_Tuple2
+ ( Eq_Type (Type_Root_of_Expr root)
+ , Expr_from AST root
+ , Lift_Type   Type_Tuple2 (Type_of_Expr root)
+ , Unlift_Type Type_Tuple2 (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr_of_Root AST root) (Error_of_Expr AST root)
+ , Root_of_Expr root ~ root
+ , IBool (Is_Last_Expr (Expr_Tuple2 root) root)
+ ) => Expr_from AST (Expr_Tuple2 root) where
+       expr_from ex ast ctx k =
+               case ast of
+                AST "(,)" asts -> from_ast2 asts tuple2_from ex ast ctx k
+                AST "fst" asts -> from_ast1 asts fst_from ex ast ctx k
+                AST "snd" asts -> from_ast1 asts snd_from ex ast ctx k
+                _ -> Left $ error_expr_unsupported ex ast
index 90146b041f919dbefaab74eede1385fac12b1047..57b2d95e2ea8fa506050988f152d72d6b0b33348 100644 (file)
@@ -50,9 +50,7 @@ type instance Root_of_Expr      (Expr_Applicative root)      = root
 type instance Type_of_Expr      (Expr_Applicative root)      = No_Type
 type instance Sym_of_Expr       (Expr_Applicative root) repr = (Sym_Applicative repr)
 type instance Error_of_Expr ast (Expr_Applicative root)      = No_Error_Expr
-instance Constraint_Type1 Applicative (Type_Type0 px root)
 instance Constraint_Type1 Applicative (Type_Var1 root)
--- instance Constraint_Type1 Applicative (Type_Type2 px root)
 
 -- | Parse 'pure'.
 pure_from
index 9dd98d022414173bba98ae9ce67784ca03502fa1..3782ae458125cec1dd447a6471ad62dad70d14ed 100644 (file)
@@ -46,7 +46,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index 5201ff741977081f7beca581a4fc3731f92f3a89..773ecd8066ff226d92caaf7f65563381cc7d8874 100644 (file)
@@ -64,7 +64,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index 6f0c870e64a4d07babbe05b9c66ffe8d8a1aad99..e316ea730cafeecae27c33f6bf3a2e81148eaf30 100644 (file)
@@ -41,7 +41,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index bc4c6a96c01f2ef5743a5d77375b12c034021506..4cb43a4ea9e287e8ce4636df693f018b8e94e207 100644 (file)
@@ -53,8 +53,6 @@ type instance Root_of_Expr      (Expr_Foldable root)      = root
 type instance Type_of_Expr      (Expr_Foldable root)      = No_Type
 type instance Sym_of_Expr       (Expr_Foldable root) repr = (Sym_Foldable repr)
 type instance Error_of_Expr ast (Expr_Foldable root)      = No_Error_Expr
-
-instance Constraint_Type1 Foldable (Type_Type0 px root)
 instance Constraint_Type1 Foldable (Type_Var1 root)
 
 -- | Parse 'foldMap'.
index 78113e0d61dc14054ada7e222a34c60b2e0fb82e..b9207e3e8adc80c9fa5a5ac9292b47dac6692dd7 100644 (file)
@@ -48,7 +48,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index 7d4ea2d2de580dc70b847a56fceed3ad7580a8b9..6f7705fd3c82d6882c6e7fdda1b282ff86b54228 100644 (file)
@@ -52,7 +52,6 @@ type instance Root_of_Expr      (Expr_Functor root)      = root
 type instance Type_of_Expr      (Expr_Functor root)      = No_Type
 type instance Sym_of_Expr       (Expr_Functor root) repr = (Sym_Functor repr)
 type instance Error_of_Expr ast (Expr_Functor root)      = No_Error_Expr
-instance Constraint_Type1 Functor (Type_Type0 px root)
 instance Constraint_Type1 Functor (Type_Var1 root)
 
 -- | Parse 'fmap'.
index bddfc19cf2c615dea58cde5fbff2fed7381e635d..0648bca227058f9e986995788a1558e7adf205cb 100644 (file)
@@ -42,7 +42,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index 0ebd3f85611b31ff66dc4974c6ca0ce4ea158484..eb5d4cc960b548f5c71fcd0648947e1a0e7cdfce 100644 (file)
@@ -38,7 +38,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index bd10dd7fcc2a103574b1e07bcac615f157a19afd..be0dca05792515fbd52446f6a0575320254d4cd5 100644 (file)
@@ -12,7 +12,6 @@ import Test.Tasty.HUnit
 
 import qualified Control.Arrow as Arrow
 import qualified Control.Monad as Monad
--- import Control.Monad.IO.Class (MonadIO(..))
 import Data.Proxy (Proxy(..))
 import Data.Text (Text)
 import Data.Type.Equality ((:~:)(Refl))
@@ -57,7 +56,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index 5d7b58fc2321ee7fa95e467337befb2d817b0f55..04d89c7c860a104cad579a1cce7dd58d52f421a3 100644 (file)
@@ -6,7 +6,7 @@ module Expr.Lambda.Test where
 
 import Test.Tasty
 
-import Prelude hiding ((&&), not, (||), (==))
+import Prelude hiding ((&&), not, (||), (==), id)
 
 import Language.Symantic.Expr.Lambda
 import Language.Symantic.Expr.Bool
index 3330bd6cdb2c082f751e53768cc6c6598ef2a209..528a47793dc2e6a66478548f0423420ef9ff5aa8 100644 (file)
@@ -9,6 +9,7 @@
 -- | Expression for 'List'.
 module Language.Symantic.Expr.List where
 
+import qualified Data.Function as Fun
 import Data.Proxy (Proxy(..))
 import Data.Type.Equality ((:~:)(Refl))
 
@@ -23,26 +24,25 @@ import Language.Symantic.Expr.Lambda
 -- | Symantic.
 class Sym_List repr where
        list_empty :: repr [a]
-       list_cons  :: repr a -> repr [a] -> repr [a]
-       list       :: [repr a] -> repr [a]
-       list_filter
-        :: repr ((->) a Bool)
-        -> repr [a]
-        -> repr [a]
+       list_cons :: repr a -> repr [a] -> repr [a]
+       list :: [repr a] -> repr [a]
+       list_filter :: repr (a -> Bool) -> repr [a] -> repr [a]
+       list_zipWith :: repr (a -> b -> c) -> repr [a] -> repr [b] -> repr [c]
+       list_reverse :: repr [a] -> repr [a]
        
-       default list_empty :: Trans t repr => t repr [a]
-       default list_cons  :: Trans t repr => t repr a -> t repr [a] -> t repr [a]
-       default list       :: Trans t repr => [t repr a] -> t repr [a]
-       default list_filter
-        :: Trans t repr
-        => t repr ((->) a Bool)
-        -> t repr [a]
-        -> t repr [a]
+       default list_empty   :: Trans t repr => t repr [a]
+       default list_cons    :: Trans t repr => t repr a -> t repr [a] -> t repr [a]
+       default list         :: Trans t repr => [t repr a] -> t repr [a]
+       default list_filter  :: Trans t repr => t repr (a -> Bool) -> t repr [a] -> t repr [a]
+       default list_zipWith :: Trans t repr => t repr (a -> b -> c) -> t repr [a] -> t repr [b] -> t repr [c]
+       default list_reverse :: Trans t repr => t repr [a] -> t repr [a]
        
-       list_empty = trans_lift list_empty
-       list_cons  = trans_map2 list_cons
-       list l     = trans_lift $ list (trans_apply Prelude.<$> l)
-       list_filter = trans_map2 list_filter
+       list_empty   = trans_lift list_empty
+       list_cons    = trans_map2 list_cons
+       list l       = trans_lift $ list (trans_apply Prelude.<$> l)
+       list_filter  = trans_map2 list_filter
+       list_zipWith = trans_map3 list_zipWith
+       list_reverse = trans_map1 list_reverse
 
 -- * Type 'Expr_List'
 -- | Expression.
@@ -88,10 +88,10 @@ list_empty_from
  ) => ast
  -> Expr_From ast (Expr_List root) hs ret
 list_empty_from ast_ty_a ex ast _ctx k =
-       either (\err -> Left $ error_expr ex $ Error_Expr_Type err ast) id $
+       either (\err -> Left $ error_expr ex $ Error_Expr_Type err ast) Fun.id $
        type_from (Proxy::Proxy ty) ast_ty_a $ \ty_a -> Right $
        k (type_list ty_a) $ Forall_Repr_with_Context $
-               const list_empty
+               Fun.const list_empty
 
 -- | Parse 'list_cons'.
 list_cons_from
@@ -114,7 +114,7 @@ list_cons_from ast_a ast_l ex ast ctx k =
        check_type_list ex ast ty_l $ \(Type_Type1 _ ty_l_a) ->
        check_eq_type ex ast ty_a ty_l_a $ \Refl ->
        k (type_list ty_a) $ Forall_Repr_with_Context $
-               \c -> list_cons (a c) (l c)
+        \c -> list_cons (a c) (l c)
 
 -- | Parse 'list'.
 list_from
@@ -143,7 +143,7 @@ list_from ast_ty_a ast_as =
           -> Expr_From ast (Expr_List root) hs ret
        go ty_a as [] _ex _ast _ctx k =
                k (type_list ty_a) $ Forall_Repr_with_Context $
-                       \c -> list ((\(Forall_Repr_with_Context a) -> a c) Prelude.<$> reverse as)
+                \c -> list ((\(Forall_Repr_with_Context a) -> a c) Prelude.<$> reverse as)
        go ty_a as (ast_x:ast_xs) ex ast ctx k =
                expr_from (Proxy::Proxy root) ast_x ctx $
                 \(ty_x::ty h_x) x ->
@@ -178,3 +178,58 @@ list_filter_from ast_f ast_l ex ast ctx k =
        check_eq_type ex ast ty_f_a ty_l_a $ \Refl ->
        k ty_l $ Forall_Repr_with_Context $
         \c -> list_filter (f c) (l c)
+
+-- | Parse 'list_zipWith'.
+list_zipWith_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_List root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Fun  (Type_of_Expr root)
+ , Unlift_Type Type_Fun  (Type_of_Expr root)
+ , Lift_Type   Type_List (Type_of_Expr root)
+ , Unlift_Type Type_List (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast -> ast -> ast
+ -> Expr_From ast (Expr_List root) hs ret
+list_zipWith_from ast_f ast_la ast_lb ex ast ctx k =
+ -- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+       expr_from (Proxy::Proxy root) ast_f ctx $
+        \(ty_f::ty h_f) (Forall_Repr_with_Context f) ->
+       expr_from (Proxy::Proxy root) ast_la ctx $
+        \(ty_la::ty h_la) (Forall_Repr_with_Context la) ->
+       expr_from (Proxy::Proxy root) ast_lb ctx $
+        \(ty_lb::ty h_lb) (Forall_Repr_with_Context lb) ->
+       check_type_fun ex ast ty_f $ \(Type_Type2 Proxy ty_f_a ty_f_b2c
+        :: Type_Fun ty h_f) ->
+       check_type_fun ex ast ty_f_b2c $ \(Type_Type2 Proxy ty_f_b ty_f_c
+        :: Type_Fun ty h_f_b2c) ->
+       check_type_list ex ast ty_la $ \(Type_Type1 _ ty_l_a) ->
+       check_type_list ex ast ty_lb $ \(Type_Type1 _ ty_l_b) ->
+       check_eq_type ex ast ty_f_a ty_l_a $ \Refl ->
+       check_eq_type ex ast ty_f_b ty_l_b $ \Refl ->
+       check_eq_type ex ast ty_f_a ty_l_a $ \Refl ->
+       k (type_list ty_f_c) $ Forall_Repr_with_Context $
+        \c -> list_zipWith (f c) (la c) (lb c)
+
+-- | Parse 'list_reverse'.
+list_reverse_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_List root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_List (Type_of_Expr root)
+ , Unlift_Type Type_List (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast
+ -> Expr_From ast (Expr_List root) hs ret
+list_reverse_from ast_l ex ast ctx k =
+       expr_from (Proxy::Proxy root) ast_l ctx $
+        \(ty_l::ty h_l) (Forall_Repr_with_Context l) ->
+       check_type_list ex ast ty_l $ \(Type_Type1 _ _ty_l_a) ->
+       k ty_l $ Forall_Repr_with_Context $
+        \c -> list_reverse (l c)
index 504cd529dd18505199688cf6928ee30ff7eb6e92..9cae8a275cb23270ce8de50b3e5a56efa5dad92e 100644 (file)
@@ -3,25 +3,25 @@
 {-# LANGUAGE NoMonomorphismRestriction #-}
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
 module Expr.List.Test where
 
 import Test.Tasty
-{-
 import Test.Tasty.HUnit
 
-import Control.Arrow (left)
+import qualified Control.Arrow as Arrow
+import qualified Control.Monad as Monad
 import Data.Proxy (Proxy(..))
 import Data.Text (Text)
 import Data.Type.Equality ((:~:)(Refl))
--}
-import Prelude hiding (mod, (==))
+import Prelude hiding (mod, (==), return)
 
--- import Language.Symantic.Repr
+import Language.Symantic.Repr
 import Language.Symantic.Expr
--- import Language.Symantic.Type
+import Language.Symantic.Type
 
--- import AST.Test
+import AST.Test
 
 -- * Expressions
 t = bool True
@@ -29,75 +29,51 @@ f = bool False
 e1 = list_filter (lam $ \x -> if_ (x `mod` int 2 == int 0) t f)
                  (list $ int Prelude.<$> [1..5])
 
-{-
 -- * Tests
+type Ex = Expr_Root
+ (   Expr_Lambda
+ .|. Expr_List
+ .|. Expr_Int
+ .|. Expr_Bool
+ )
+ex_from = root_expr_from (Proxy::Proxy Ex)
+
 (==>) ast expected =
        testCase (show ast) $
-       case ex_from (Proxy::Proxy IO) ast of
-        Left err -> Left err @?= snd `left` expected
+       case ex_from ast of
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
-                Right (ty_expected::Type_Root_of_Expr (Ex IO) h, _::h, _::Text) ->
-                       (>>= (@?= (\(_::Proxy h, err) -> err) `left` expected)) $
+                Right (ty_expected::Type_Root_of_Expr Ex h, _::h, _::Text) ->
+                       (Monad.>>= (@?= (\(_::Proxy h, err) -> err) `Arrow.left` expected)) $
                        case ty `eq_type` ty_expected of
-                        Nothing -> return $ Left $
-                               error_expr (Proxy::Proxy (Ex IO)) $
+                        Nothing -> Monad.return $ Left $
+                               error_expr (Proxy::Proxy Ex) $
                                Error_Expr_Type_mismatch ast
                                 (Exists_Type ty)
                                 (Exists_Type ty_expected)
                         Just Refl -> do
-                               h <- host_from_expr r
-                               return $
+                               let h = host_from_expr r
+                               Monad.return $
                                        Right
                                         ( ty
                                         , h
                                         , text_from_expr r
-                                        -- , (text_from_expr :: Repr_String IO h -> Text) r
+                                        -- , (text_from_expr :: Repr_Text h -> Text) r
                                         )
--}
+
 tests :: TestTree
 tests = testGroup "List"
- [{- AST "just" [AST "bool" [AST "True" []]] ==> Right
-        ( type_maybe type_bool
-        , Just True
-        , "just True" )
- , AST "just"
-        [ AST "let"
-                [ AST "x" []
-                , AST "bool" [AST "True" []]
-                , AST "var" [AST "x" []]
-                ]
-        ] ==> Right
-        ( type_maybe type_bool
-        , Just True
-        , "just (let x0 = True in x0)" )
- , AST "maybe"
-        [ AST "bool" [AST "True" []]
-        , AST "\\"
-                [ AST "x" []
-                , AST "Bool" []
-                , AST "not" [AST "var" [AST "x" []]]
-                ]
-        , AST "nothing"
-                [ AST "Bool" []
-                ]
-        ] ==> Right
-        ( type_bool
-        , True
-        , "maybe True (\\x0 -> !x0) nothing" )
- , AST "maybe"
-        [ AST "bool" [AST "False" []]
-        , AST "\\"
-                [ AST "x" []
-                , AST "Bool" []
-                , AST "not" [AST "var" [AST "x" []]]
-                ]
-        , AST "just"
-                [ AST "bool" [AST "True" []]
+ [ AST "list_reverse"
+        [ AST "list"
+                [ AST "Int" []
+                , AST "int" [AST "1" []]
+                , AST "int" [AST "2" []]
+                , AST "int" [AST "3" []]
                 ]
         ] ==> Right
-        ( type_bool
-        , False
-        , "maybe False (\\x0 -> !x0) (just True)" )
-}]
+        ( type_list type_int
+        , [3,2,1]
+        , "list_reverse [1, 2, 3]" )
+ ]
index 2ab9009fb212de4801aff4bb39eeb416c5e497e0..96923e64437cffa1db802f60f601ce433bfed465 100644 (file)
@@ -9,6 +9,7 @@
 module Language.Symantic.Expr.Map where
 
 import Data.Map.Strict (Map)
+-- import qualified Data.Map.Strict as Map
 import Data.Proxy (Proxy(..))
 import Data.Type.Equality ((:~:)(Refl))
 
@@ -25,20 +26,34 @@ import Language.Symantic.Expr.Tuple
 -- | Symantic.
 class Sym_Map repr where
        map_from_list :: Ord k => repr [(k, a)] -> repr (Map k a)
-       mapWithKey
-        :: repr (k -> a -> b)
-        -> repr (Map k a)
-        -> repr (Map k b)
+       mapWithKey :: repr (k -> a -> b) -> repr (Map k a) -> repr (Map k b)
+       map_lookup :: Ord k => repr k -> repr (Map k a) -> repr (Maybe a)
+       map_keys :: repr (Map k a) -> repr [k]
+       map_member :: Ord k => repr k -> repr (Map k a) -> repr Bool
+       map_insert :: Ord k => repr k -> repr a -> repr (Map k a) -> repr (Map k a)
+       map_delete :: Ord k => repr k -> repr (Map k a) -> repr (Map k a)
+       map_difference :: Ord k => repr (Map k a) -> repr (Map k b) -> repr (Map k a)
+       map_foldrWithKey :: repr (k -> a -> b -> b) -> repr b -> repr (Map k a) -> repr b
        
        default map_from_list :: (Trans t repr, Ord k) => t repr [(k, a)] -> t repr (Map k a)
-       default mapWithKey
-        :: Trans t repr
-        => t repr (k -> a -> b)
-        -> t repr (Map k a)
-        -> t repr (Map k b)
+       default mapWithKey :: Trans t repr => t repr (k -> a -> b) -> t repr (Map k a) -> t repr (Map k b)
+       default map_lookup :: (Trans t repr, Ord k) => t repr k -> t repr (Map k a) -> t repr (Maybe a)
+       default map_keys :: (Trans t repr, Ord k) => t repr (Map k a) -> t repr [k]
+       default map_member :: (Trans t repr, Ord k) => t repr k -> t repr (Map k a) -> t repr Bool
+       default map_insert :: (Trans t repr, Ord k) => t repr k -> t repr a -> t repr (Map k a) -> t repr (Map k a)
+       default map_delete :: (Trans t repr, Ord k) => t repr k -> t repr (Map k a) -> t repr (Map k a)
+       default map_difference :: (Trans t repr, Ord k) => t repr (Map k a) -> t repr (Map k b) -> t repr (Map k a)
+       default map_foldrWithKey :: Trans t repr => t repr (k -> a -> b -> b) -> t repr b -> t repr (Map k a) -> t repr b
        
-       map_from_list = trans_map1 map_from_list
-       mapWithKey    = trans_map2 mapWithKey
+       map_from_list    = trans_map1 map_from_list
+       mapWithKey       = trans_map2 mapWithKey
+       map_lookup       = trans_map2 map_lookup
+       map_keys         = trans_map1 map_keys
+       map_member       = trans_map2 map_member
+       map_insert       = trans_map3 map_insert
+       map_delete       = trans_map2 map_delete
+       map_difference   = trans_map2 map_difference
+       map_foldrWithKey = trans_map3 map_foldrWithKey
 
 -- | Parsing utility to check that the given type is a 'Type_List'
 -- or raise 'Error_Expr_Type_mismatch'.
@@ -97,15 +112,15 @@ mapWithKey_from
  , Expr_from ast root
  , Lift_Type   Type_Fun (Type_of_Expr root)
  , Unlift_Type Type_Fun (Type_of_Expr root)
- , Lift_Type   Type_Map       (Type_of_Expr root)
- , Unlift_Type Type_Map       (Type_of_Expr root)
- , Constraint_Type Ord ty
+ , Lift_Type   Type_Map (Type_of_Expr root)
+ , Unlift_Type Type_Map (Type_of_Expr root)
  , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
                    (Error_of_Expr ast root)
  , Root_of_Expr root ~ root
  ) => ast -> ast
  -> Expr_From ast (Expr_Map root) hs ret
 mapWithKey_from ast_f ast_m ex ast ctx k =
+ -- mapWithKey :: (k -> a -> b) -> Map k a -> Map k b
        expr_from (Proxy::Proxy root) ast_f ctx $
         \(ty_f::ty h_f) (Forall_Repr_with_Context f) ->
        expr_from (Proxy::Proxy root) ast_m ctx $
@@ -117,10 +132,203 @@ mapWithKey_from ast_f ast_m ex ast ctx k =
        check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k ty_m_a) ->
        check_eq_type ex ast ty_f_k ty_m_k $ \Refl ->
        check_eq_type ex ast ty_f_a ty_m_a $ \Refl ->
-       check_constraint_type ex (Proxy::Proxy Ord) ast ty_m_k $ \Dict ->
        k (type_map ty_m_k ty_f_b) $ Forall_Repr_with_Context $
         \c -> mapWithKey (f c) (m c)
 
+-- | Parse 'map_lookup'.
+map_lookup_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Map   (Type_of_Expr root)
+ , Unlift_Type Type_Map   (Type_of_Expr root)
+ , Lift_Type   Type_Maybe (Type_of_Expr root)
+ , Constraint_Type Ord ty
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast -> ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_lookup_from ast_k ast_m ex ast ctx k =
+ -- lookup :: Ord k => k -> Map k a -> Maybe a
+       expr_from (Proxy::Proxy root) ast_k ctx $
+        \(ty_k::ty h_k) (Forall_Repr_with_Context key) ->
+       expr_from (Proxy::Proxy root) ast_m ctx $
+        \(ty_m::ty h_m) (Forall_Repr_with_Context m) ->
+       check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k ty_m_a) ->
+       check_eq_type ex ast ty_k ty_m_k $ \Refl ->
+       check_constraint_type ex (Proxy::Proxy Ord) ast ty_k $ \Dict ->
+       k (type_maybe ty_m_a) $ Forall_Repr_with_Context $
+        \c -> map_lookup (key c) (m c)
+
+-- | Parse 'map_keys'.
+map_keys_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Map  (Type_of_Expr root)
+ , Unlift_Type Type_Map  (Type_of_Expr root)
+ , Lift_Type   Type_List (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_keys_from ast_m ex ast ctx k =
+ -- keys :: Map k a -> [k]
+       expr_from (Proxy::Proxy root) ast_m ctx $
+        \(ty_m::ty h_m) (Forall_Repr_with_Context m) ->
+       check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k _ty_m_a) ->
+       k (type_list ty_m_k) $ Forall_Repr_with_Context $
+        \c -> map_keys (m c)
+
+-- | Parse 'map_member'.
+map_member_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Constraint_Type Ord ty
+ , Lift_Type   Type_Map  (Type_of_Expr root)
+ , Unlift_Type Type_Map  (Type_of_Expr root)
+ , Lift_Type   Type_Bool (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast -> ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_member_from ast_k ast_m ex ast ctx k =
+ -- member :: Ord k => k -> Map k a -> Bool
+       expr_from (Proxy::Proxy root) ast_k ctx $
+        \(ty_k::ty h_k) (Forall_Repr_with_Context key) ->
+       expr_from (Proxy::Proxy root) ast_m ctx $
+        \(ty_m::ty h_m) (Forall_Repr_with_Context m) ->
+       check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k _ty_m_a) ->
+       check_eq_type ex ast ty_k ty_m_k $ \Refl ->
+       check_constraint_type ex (Proxy::Proxy Ord) ast ty_k $ \Dict ->
+       k type_bool $ Forall_Repr_with_Context $
+        \c -> map_member (key c) (m c)
+
+-- | Parse 'map_insert'.
+map_insert_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Constraint_Type Ord ty
+ , Lift_Type   Type_Map (Type_of_Expr root)
+ , Unlift_Type Type_Map (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast -> ast -> ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_insert_from ast_k ast_a ast_m ex ast ctx k =
+ -- insert :: Ord k => k -> a -> Map k a -> Map k a
+       expr_from (Proxy::Proxy root) ast_k ctx $
+        \(ty_k::ty h_k) (Forall_Repr_with_Context key) ->
+       expr_from (Proxy::Proxy root) ast_a ctx $
+        \(ty_a::ty h_a) (Forall_Repr_with_Context a) ->
+       expr_from (Proxy::Proxy root) ast_m ctx $
+        \(ty_m::ty h_m) (Forall_Repr_with_Context m) ->
+       check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k ty_m_a) ->
+       check_eq_type ex ast ty_k ty_m_k $ \Refl ->
+       check_eq_type ex ast ty_a ty_m_a $ \Refl ->
+       check_constraint_type ex (Proxy::Proxy Ord) ast ty_k $ \Dict ->
+       k ty_m $ Forall_Repr_with_Context $
+        \c -> map_insert (key c) (a c) (m c)
+
+-- | Parse 'map_delete'.
+map_delete_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Map (Type_of_Expr root)
+ , Unlift_Type Type_Map (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Constraint_Type Ord ty
+ , Root_of_Expr root ~ root
+ ) => ast -> ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_delete_from ast_k ast_m ex ast ctx k =
+ -- delete :: Ord k => k -> Map k a -> Map k a
+       expr_from (Proxy::Proxy root) ast_k ctx $
+        \(ty_k::ty h_k) (Forall_Repr_with_Context key) ->
+       expr_from (Proxy::Proxy root) ast_m ctx $
+        \(ty_m::ty h_m) (Forall_Repr_with_Context m) ->
+       check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k _ty_m_a) ->
+       check_eq_type ex ast ty_k ty_m_k $ \Refl ->
+       check_constraint_type ex (Proxy::Proxy Ord) ast ty_k $ \Dict ->
+       k ty_m $ Forall_Repr_with_Context $
+        \c -> map_delete (key c) (m c)
+
+-- | Parse 'map_difference'.
+map_difference_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Map (Type_of_Expr root)
+ , Unlift_Type Type_Map (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Constraint_Type Ord ty
+ , Root_of_Expr root ~ root
+ ) => ast -> ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_difference_from ast_ma ast_mb ex ast ctx k =
+ -- difference :: Ord k => Map k a -> Map k b -> Map k a
+       expr_from (Proxy::Proxy root) ast_ma ctx $
+        \(ty_ma::ty h_ma) (Forall_Repr_with_Context ma) ->
+       expr_from (Proxy::Proxy root) ast_mb ctx $
+        \(ty_mb::ty h_mb) (Forall_Repr_with_Context mb) ->
+       check_type_map ex ast ty_ma $ \(Type_Type2 Proxy ty_ma_k _ty_ma_a) ->
+       check_type_map ex ast ty_mb $ \(Type_Type2 Proxy ty_mb_k _ty_mb_b) ->
+       check_eq_type ex ast ty_ma_k ty_mb_k $ \Refl ->
+       check_constraint_type ex (Proxy::Proxy Ord) ast ty_ma_k $ \Dict ->
+       k ty_ma $ Forall_Repr_with_Context $
+        \c -> map_difference (ma c) (mb c)
+
+-- | Parse 'map_foldrWithKey'.
+map_foldrWithKey_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Map root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Fun (Type_of_Expr root)
+ , Unlift_Type Type_Fun (Type_of_Expr root)
+ , Lift_Type   Type_Map (Type_of_Expr root)
+ , Unlift_Type Type_Map (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Constraint_Type Ord ty
+ , Root_of_Expr root ~ root
+ ) => ast -> ast -> ast
+ -> Expr_From ast (Expr_Map root) hs ret
+map_foldrWithKey_from ast_f ast_b ast_m ex ast ctx k =
+ -- foldrWithKey :: (k -> a -> b -> b) -> b -> Map k a -> b
+       expr_from (Proxy::Proxy root) ast_f ctx $
+        \(ty_f::ty h_f) (Forall_Repr_with_Context f) ->
+       expr_from (Proxy::Proxy root) ast_b ctx $
+        \(ty_b::ty h_b) (Forall_Repr_with_Context b) ->
+       expr_from (Proxy::Proxy root) ast_m ctx $
+        \(ty_m::ty h_m) (Forall_Repr_with_Context m) ->
+       check_type_fun ex ast ty_f $ \(Type_Type2 Proxy ty_f_k ty_f_a2b2b) ->
+       check_type_fun ex ast ty_f_a2b2b $ \(Type_Type2 Proxy ty_f_a ty_f_b2b) ->
+       check_type_fun ex ast ty_f_b2b $ \(Type_Type2 Proxy ty_f_b ty_f_b') ->
+       check_type_map ex ast ty_m $ \(Type_Type2 Proxy ty_m_k ty_m_a) ->
+       check_eq_type ex ast ty_f_k ty_m_k $ \Refl ->
+       check_eq_type ex ast ty_f_a ty_m_a $ \Refl ->
+       check_eq_type ex ast ty_b ty_f_b $ \Refl ->
+       check_eq_type ex ast ty_f_b ty_f_b' $ \Refl ->
+       check_constraint_type ex (Proxy::Proxy Ord) ast ty_m_k $ \Dict ->
+       k ty_b $ Forall_Repr_with_Context $
+        \c -> map_foldrWithKey (f c) (b c) (m c)
+
 -- * Type 'Expr_Map'
 -- | Expression.
 data Expr_Map (root:: *)
@@ -128,14 +336,3 @@ type instance Root_of_Expr      (Expr_Map root)      = root
 type instance Type_of_Expr      (Expr_Map root)      = Type_Map
 type instance Sym_of_Expr       (Expr_Map root) repr = (Sym_Map repr)
 type instance Error_of_Expr ast (Expr_Map root)      = No_Error_Expr
-
-instance Constraint_Type1 Functor (Type_Map root) where
-       constraint_type1 _c Type_Type2{} = Just Dict
-instance Constraint_Type1 Functor (Type_Type1 (Proxy (Map k)) root) where
-       constraint_type1 _c Type_Type1{} = Just Dict
-instance Constraint_Type1 Applicative (Type_Map root)
-instance Constraint_Type1 Applicative (Type_Type1 (Proxy (Map k)) root)
-instance Constraint_Type1 Traversable (Type_Map root) where
-       constraint_type1 _c Type_Type2{} = Just Dict
-instance Constraint_Type1 Traversable (Type_Type1 (Proxy (Map k)) root) where
-       constraint_type1 _c Type_Type1{} = Just Dict
diff --git a/Language/Symantic/Expr/Map/HLint.hs b/Language/Symantic/Expr/Map/HLint.hs
new file mode 120000 (symlink)
index 0000000..ab18269
--- /dev/null
@@ -0,0 +1 @@
+../HLint.hs
\ No newline at end of file
diff --git a/Language/Symantic/Expr/Map/Test.hs b/Language/Symantic/Expr/Map/Test.hs
new file mode 100644 (file)
index 0000000..d89b442
--- /dev/null
@@ -0,0 +1,169 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+module Expr.Map.Test where
+
+import Test.Tasty
+import Test.Tasty.HUnit
+
+import qualified Control.Arrow as Arrow
+import qualified Control.Monad as Monad
+-- import qualified Data.List as List
+import qualified Data.Map.Strict as Map
+import Data.Proxy (Proxy(..))
+import Data.Text (Text)
+import qualified Data.Text as Text
+import Data.Type.Equality ((:~:)(Refl))
+import Prelude hiding (maybe, not)
+
+import Language.Symantic.Repr
+import Language.Symantic.Expr
+import Language.Symantic.Type
+
+import AST.Test
+
+-- * Expressions
+t = bool True
+f = bool False
+e1 = map_from_list $ list_zipWith (lam (lam . tuple2))
+ (list $ int Prelude.<$> [1..5])
+ (list $ (text . Text.singleton) Prelude.<$> ['a'..'e'])
+
+-- * Tests
+type Ex = Expr_Root
+ (   Expr_Lambda
+ .|. Expr_Map
+ .|. Expr_Bool
+ .|. Expr_Maybe
+ .|. Expr_List
+ .|. Expr_Eq
+ .|. Expr_Ord
+ .|. Expr_Tuple2
+ .|. Expr_Int
+ .|. Expr_Text
+ .|. Expr_Monoid
+ )
+ex_from = root_expr_from (Proxy::Proxy Ex)
+
+(==>) ast expected =
+       testCase (show ast) $
+       case ex_from ast of
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
+        Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
+               case expected of
+                Left (_, err) -> Right ("…"::String) @?= Left err
+                Right (ty_expected::Type_Root_of_Expr Ex h, _::h, _::Text) ->
+                       (Monad.>>= (@?= (\(_::Proxy h, err) -> err) `Arrow.left` expected)) $
+                       case ty `eq_type` ty_expected of
+                        Nothing -> Monad.return $ Left $
+                               error_expr (Proxy::Proxy Ex) $
+                               Error_Expr_Type_mismatch ast
+                                (Exists_Type ty)
+                                (Exists_Type ty_expected)
+                        Just Refl -> do
+                               let h = host_from_expr r
+                               Monad.return $
+                                       Right
+                                        ( ty
+                                        , h
+                                        , text_from_expr r
+                                        -- , (text_from_expr :: Repr_Text h -> Text) r
+                                        )
+
+tests :: TestTree
+tests = testGroup "Map"
+ [ AST "map_from_list"
+        [ AST "list_zipWith"
+                [ AST "\\"
+                        [ AST "x" []
+                        , AST "Int" []
+                        , AST "\\"
+                                [ AST "y" []
+                                , AST "Text" []
+                                , AST "(,)"
+                                        [ AST "var" [AST "x" []]
+                                        , AST "var" [AST "y" []]
+                                        ]
+                                ]
+                        ]
+                , AST "list"
+                        [ AST "Int" []
+                        , AST "int" [AST "1" []]
+                        , AST "int" [AST "2" []]
+                        , AST "int" [AST "3" []]
+                        ]
+                , AST "list"
+                        [ AST "Text" []
+                        , AST "text" [AST "a" []]
+                        , AST "text" [AST "b" []]
+                        , AST "text" [AST "c" []]
+                        ]
+                ]
+        ] ==> Right
+        ( type_map type_int type_text
+        , Map.fromList [(1, "a"), (2, "b"), (3, "c")]
+        , "map_from_list (list_zipWith (\\x0 -> (\\x1 -> (x0, x1))) [1, 2, 3] [\"a\", \"b\", \"c\"])" )
+ , AST "map_foldrWithKey"
+        [ AST "\\"
+                [ AST "k" []
+                , AST "Int" []
+                , AST "\\"
+                        [ AST "v" []
+                        , AST "Text" []
+                        , AST "\\"
+                                [ AST "a" []
+                                , AST "(,)" [AST "Int" [], AST "Text" []]
+                                , AST "(,)"
+                                        [ AST "+"
+                                                [ AST "var" [AST "k" []]
+                                                , AST "fst" [ AST "var" [AST "a" []] ]
+                                                ]
+                                        , AST "mappend"
+                                                [ AST "var" [AST "v" []]
+                                                , AST "snd" [ AST "var" [AST "a" []] ]
+                                                ]
+                                        ]
+                                ]
+                        ]
+                ]
+        , AST "(,)"
+                [ AST "int" [AST "0" []]
+                , AST "text" [AST "" []]
+                ]
+        , AST "map_from_list"
+                [ AST "list_zipWith"
+                        [ AST "\\"
+                                [ AST "x" []
+                                , AST "Int" []
+                                , AST "\\"
+                                        [ AST "y" []
+                                        , AST "Text" []
+                                        , AST "(,)"
+                                                [ AST "var" [AST "x" []]
+                                                , AST "var" [AST "y" []]
+                                                ]
+                                        ]
+                                ]
+                        , AST "list"
+                                [ AST "Int" []
+                                , AST "int" [AST "1" []]
+                                , AST "int" [AST "2" []]
+                                , AST "int" [AST "3" []]
+                                ]
+                        , AST "list"
+                                [ AST "Text" []
+                                , AST "text" [AST "a" []]
+                                , AST "text" [AST "b" []]
+                                , AST "text" [AST "c" []]
+                                ]
+                        ]
+                ]
+        ] ==> Right
+        ( type_tuple2 type_int type_text
+        , (6, "abc")
+        , "map_foldrWithKey (\\x0 -> (\\x1 -> (\\x2 -> (x0 + fst x2, mappend x1 (snd x2))))) (0, \"\") (map_from_list (list_zipWith (\\x0 -> (\\x1 -> (x0, x1))) [1, 2, 3] [\"a\", \"b\", \"c\"]))" )
+ ]
index fb2df7a94491338ca2ab063341df1305f52884a0..ad04538378a3571a21da3d65ea06cf6b10a69a18 100644 (file)
@@ -9,6 +9,7 @@
 -- | Expression for 'Maybe'.
 module Language.Symantic.Expr.Maybe where
 
+import qualified Data.Function as Fun
 import Data.Proxy (Proxy(..))
 import Data.Type.Equality ((:~:)(Refl))
 import Prelude hiding (maybe)
@@ -123,7 +124,7 @@ nothing_from ast_ty_a ex ast _ctx k =
         Left err -> Left $ error_expr ex $ Error_Expr_Type err ast
         Right (Exists_Type ty_a) ->
                k (type_maybe ty_a) $ Forall_Repr_with_Context $
-                       const nothing
+                       Fun.const nothing
 
 -- | Parse 'just'.
 just_from
@@ -137,5 +138,5 @@ just_from
 just_from ast_a _ex _ast ctx k =
        expr_from (Proxy::Proxy root) ast_a ctx $
         \(ty_a::ty h_a) (Forall_Repr_with_Context a) ->
-               k (type_maybe ty_a) $ Forall_Repr_with_Context $
-                       \c -> just (a c)
+       k (type_maybe ty_a) $ Forall_Repr_with_Context $
+        \c -> just (a c)
index eb1cccc4d7b04bedf65bc934a40629b9f23606fb..fd7c553eb4f3da95b3e9063c681dc528b4a4c9fb 100644 (file)
@@ -37,7 +37,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index a3c0eed97b26e6871064de53bc294151c688ec82..789fc6bf5fd921d6bcf37bd2fa2be9eccaa48b75 100644 (file)
@@ -12,7 +12,7 @@
 module Language.Symantic.Expr.Monad where
 
 import Control.Monad (Monad)
--- import qualified Control.Monad as Monad
+import qualified Data.Function as Fun
 import Data.Proxy (Proxy(..))
 import Data.Type.Equality ((:~:)(Refl))
 import Prelude hiding ((<$>), Monad(..))
@@ -47,7 +47,6 @@ type instance Root_of_Expr      (Expr_Monad root)      = root
 type instance Type_of_Expr      (Expr_Monad root)      = No_Type
 type instance Sym_of_Expr       (Expr_Monad root) repr = (Sym_Monad repr)
 type instance Error_of_Expr ast (Expr_Monad root)      = No_Error_Expr
-instance Constraint_Type1 Monad (Type_Type0 px root)
 instance Constraint_Type1 Monad (Type_Var1 root)
 
 return_from
@@ -64,7 +63,7 @@ return_from
  -> Expr_From ast (Expr_Monad root) hs ret
 return_from ast_f ast_a ex ast ctx k =
  -- return :: Monad f => a -> f a
-       either (\err -> Left $ error_expr ex $ Error_Expr_Type err ast) id $
+       either (\err -> Left $ error_expr ex $ Error_Expr_Type err ast) Fun.id $
        type1_from (Proxy::Proxy ty) ast_f $ \_f ty_f -> Right $
                expr_from (Proxy::Proxy root) ast_a ctx $
                 \(ty_a::ty h_a) (Forall_Repr_with_Context a) ->
index 71c388fe77ed236c368094e0be3b48813dabbe66..d79d9a410ab20cbac4e08645cce328e6cded2d7e 100644 (file)
@@ -48,7 +48,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index f387c8f99764c7d3c002b719afd55b0654143da2..c8e1b38d07e3d7e55e4ecf8fbbbfd40b8154c424 100644 (file)
@@ -14,6 +14,7 @@ import qualified Expr.Applicative.Test as Applicative
 import qualified Expr.Foldable.Test as Foldable
 import qualified Expr.Traversable.Test as Traversable
 import qualified Expr.Monad.Test as Monad
+import qualified Expr.Map.Test as Map
 
 tests :: TestTree
 tests =
@@ -30,4 +31,5 @@ tests =
         , Foldable.tests
         , Traversable.tests
         , Monad.tests
+        , Map.tests
         ]
index d577577bc0c09974fefffd7f5d1c3c048e2321b0..d947c3bbc7cf7e67a8cae9c1eb489394f9a056b9 100644 (file)
@@ -41,7 +41,6 @@ type instance Root_of_Expr      (Expr_Traversable root)      = root
 type instance Type_of_Expr      (Expr_Traversable root)      = No_Type
 type instance Sym_of_Expr       (Expr_Traversable root) repr = (Sym_Traversable repr)
 type instance Error_of_Expr ast (Expr_Traversable root)      = No_Error_Expr
-instance Constraint_Type1 Traversable (Type_Type0 px root)
 instance Constraint_Type1 Traversable (Type_Var1 root)
 
 traverse_from
index a2a7457f5b876bf24c26bfaa64e06ac7e095147e..72de5c4d9e897f889d31b8632f0a58d829b8754d 100644 (file)
@@ -48,7 +48,7 @@ ex_from = root_expr_from (Proxy::Proxy Ex)
 (==>) ast expected =
        testCase (show ast) $
        case ex_from ast of
-        Left err -> Left err @?= snd `Arrow.left` expected
+        Left err -> Left err @?= Prelude.snd `Arrow.left` expected
         Right (Exists_Type_and_Repr ty (Forall_Repr r)) ->
                case expected of
                 Left (_, err) -> Right ("…"::String) @?= Left err
index f080749ffef9366653eaa61da626799f443206da..f02ceeb65fb27e197cf42ce9267080bd5e305257 100644 (file)
@@ -9,7 +9,7 @@
 module Language.Symantic.Expr.Tuple where
 
 import Data.Proxy (Proxy(..))
-import Prelude hiding (maybe)
+import Prelude hiding (maybe, fst, snd)
 
 import Language.Symantic.Type
 import Language.Symantic.Trans.Common
@@ -21,8 +21,16 @@ import Language.Symantic.Expr.From
 -- | Symantic.
 class Sym_Tuple2 repr where
        tuple2 :: repr a -> repr b -> repr (a, b)
+       fst :: repr (a, b) -> repr a
+       snd :: repr (a, b) -> repr b
+       
        default tuple2 :: Trans t repr => t repr a -> t repr b -> t repr (a, b)
+       default fst :: Trans t repr => t repr (a, b) -> t repr a
+       default snd :: Trans t repr => t repr (a, b) -> t repr b
+       
        tuple2 = trans_map2 tuple2
+       fst    = trans_map1 fst
+       snd    = trans_map1 snd
 
 -- * Type 'Expr_Tuple2'
 -- | Expression.
@@ -32,12 +40,6 @@ type instance Type_of_Expr      (Expr_Tuple2 root)      = Type_Tuple2
 type instance Sym_of_Expr       (Expr_Tuple2 root) repr = (Sym_Tuple2 repr)
 type instance Error_of_Expr ast (Expr_Tuple2 root)      = No_Error_Expr
 
-instance Constraint_Type1 Functor (Type_Type1 (Proxy ((,) fst)) root) where
-       constraint_type1 _c Type_Type1{} = Just Dict
-instance Constraint_Type1 Functor (Type_Tuple2 root) where
-       constraint_type1 _c Type_Type2{} = Just Dict
-instance Constraint_Type1 Applicative (Type_Type1 (Proxy ((,) fst)) root)
-
 -- | Parsing utility to check that the given type is a 'Type_Tuple2'
 -- or raise 'Error_Expr_Type_mismatch'.
 check_type_tuple2
@@ -81,4 +83,44 @@ tuple2_from ast_a ast_b _ex _ast ctx k =
        expr_from (Proxy::Proxy root) ast_b ctx $
         \(ty_b::ty h_b) (Forall_Repr_with_Context b) ->
        k (type_tuple2 ty_a ty_b) $ Forall_Repr_with_Context $
-               \c -> tuple2 (a c) (b c)
+        \c -> tuple2 (a c) (b c)
+
+-- | Parse 'fst'.
+fst_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Tuple2 root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Tuple2 (Type_of_Expr root)
+ , Unlift_Type Type_Tuple2 (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast
+ -> Expr_From ast (Expr_Tuple2 root) hs ret
+fst_from ast_t ex ast ctx k =
+       expr_from (Proxy::Proxy root) ast_t ctx $
+        \(ty_t::ty h_t) (Forall_Repr_with_Context t) ->
+       check_type_tuple2 ex ast ty_t $ \(Type_Type2 _ ty_a _ty_b) ->
+       k ty_a $ Forall_Repr_with_Context $
+        \c -> fst (t c)
+
+-- | Parse 'snd'.
+snd_from
+ :: forall root ty ast hs ret.
+ ( ty ~ Type_Root_of_Expr (Expr_Tuple2 root)
+ , Eq_Type ty
+ , Expr_from ast root
+ , Lift_Type   Type_Tuple2 (Type_of_Expr root)
+ , Unlift_Type Type_Tuple2 (Type_of_Expr root)
+ , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
+                   (Error_of_Expr ast root)
+ , Root_of_Expr root ~ root
+ ) => ast
+ -> Expr_From ast (Expr_Tuple2 root) hs ret
+snd_from ast_t ex ast ctx k =
+       expr_from (Proxy::Proxy root) ast_t ctx $
+        \(ty_t::ty h_t) (Forall_Repr_with_Context t) ->
+       check_type_tuple2 ex ast ty_t $ \(Type_Type2 _ _ty_a ty_b) ->
+       k ty_b $ Forall_Repr_with_Context $
+        \c -> snd (t c)
index 9dcc0c4646851c5ae56797c4c50821b47a06dc16..6e095ea1e174ef02f4e1151ca70cdb75801e358c 100644 (file)
@@ -81,6 +81,10 @@ instance -- Sym_List
                list l1 `Dup` list l2
        list_filter (f1 `Dup` f2) (l1 `Dup` l2) =
                list_filter f1 l1 `Dup` list_filter f2 l2
+       list_zipWith (f1 `Dup` f2) (la1 `Dup` la2) (lb1 `Dup` lb2) =
+               list_zipWith f1 la1 lb1 `Dup` list_zipWith f2 la2 lb2
+       list_reverse (l1 `Dup` l2) =
+               list_reverse l1 `Dup` list_reverse l2
 instance -- Sym_Maybe
  ( Sym_Maybe r1
  , Sym_Maybe r2
@@ -102,6 +106,8 @@ instance -- Sym_Tuple2
  ) => Sym_Tuple2 (Dup r1 r2) where
        tuple2 (a1 `Dup` a2) (b1 `Dup` b2) =
                tuple2 a1 b1 `Dup` tuple2 a2 b2
+       fst (t1 `Dup` t2) = fst t1 `Dup` fst t2
+       snd (t1 `Dup` t2) = snd t1 `Dup` snd t2
 instance -- Sym_Map
  ( Sym_Map r1
  , Sym_Map r2
@@ -110,6 +116,20 @@ instance -- Sym_Map
                map_from_list l1 `Dup` map_from_list l2
        mapWithKey (f1 `Dup` f2) (m1 `Dup` m2) =
                mapWithKey f1 m1 `Dup` mapWithKey f2 m2
+       map_lookup (k1 `Dup` k2) (m1 `Dup` m2) =
+               map_lookup k1 m1 `Dup` map_lookup k2 m2
+       map_keys (m1 `Dup` m2) =
+               map_keys m1 `Dup` map_keys m2
+       map_member (k1 `Dup` k2) (m1 `Dup` m2) =
+               map_member k1 m1 `Dup` map_member k2 m2
+       map_insert (k1 `Dup` k2) (a1 `Dup` a2) (m1 `Dup` m2) =
+               map_insert k1 a1 m1 `Dup` map_insert k2 a2 m2
+       map_delete (k1 `Dup` k2) (m1 `Dup` m2) =
+               map_delete k1 m1 `Dup` map_delete k2 m2
+       map_difference (ma1 `Dup` ma2) (mb1 `Dup` mb2) =
+               map_difference ma1 mb1 `Dup` map_difference ma2 mb2
+       map_foldrWithKey (f1 `Dup` f2) (b1 `Dup` b2) (m1 `Dup` m2) =
+               map_foldrWithKey f1 b1 m1 `Dup` map_foldrWithKey f2 b2 m2
 instance -- Sym_Functor
  ( Sym_Functor r1
  , Sym_Functor r2
index a37d0acf895bfedf597eb367fcedc6d40e5244d9..9a7da6aca73abb3550e68dcb827b93546b254aed 100644 (file)
@@ -14,6 +14,7 @@ import Data.Foldable as Foldable
 import Data.Functor as Functor
 import Data.Monoid as Monoid
 import Data.Traversable as Traversable
+import qualified Data.Tuple as Tuple
 import qualified Data.Bool as Bool
 import qualified Data.List as List
 import qualified Data.Map.Strict as Map
@@ -75,15 +76,26 @@ instance Sym_Eq Repr_Host where
 instance Sym_Ord Repr_Host where
        compare = liftM2 Prelude.compare
 instance Sym_List Repr_Host where
-       list_empty  = return []
-       list_cons   = liftM2 (:)
-       list        = sequence
-       list_filter = liftM2 List.filter
+       list_empty   = return []
+       list_cons    = liftM2 (:)
+       list         = sequence
+       list_filter  = liftM2 List.filter
+       list_zipWith = liftM3 List.zipWith
+       list_reverse = liftM  List.reverse
 instance Sym_Tuple2 Repr_Host where
        tuple2 = liftM2 (,)
+       fst    = liftM  Tuple.fst
+       snd    = liftM  Tuple.snd
 instance Sym_Map Repr_Host where
-       map_from_list = liftM Map.fromList
-       mapWithKey    = liftM2 Map.mapWithKey
+       map_from_list    = liftM  Map.fromList
+       mapWithKey       = liftM2 Map.mapWithKey
+       map_lookup       = liftM2 Map.lookup
+       map_keys         = liftM  Map.keys
+       map_member       = liftM2 Map.member
+       map_insert       = liftM3 Map.insert
+       map_delete       = liftM2 Map.delete
+       map_difference   = liftM2 Map.difference
+       map_foldrWithKey = liftM3 Map.foldrWithKey
 instance Sym_Functor Repr_Host where
        fmap = liftM2 (Functor.<$>)
 instance Expr.Sym_Monad Repr_Host where
index d2ab171aa0016aac47a14378ef24ed3f0810fb85..6d5218587a8d089de8e4ce698c432ff167984c84 100644 (file)
@@ -13,7 +13,7 @@ import Test.Tasty.HUnit
 
 import Data.Text (Text)
 import qualified Data.Text as Text
-import Prelude hiding (and, not, or, Monad(..))
+import Prelude hiding (and, not, or, Monad(..), id)
 
 import Language.Symantic.Repr
 import Language.Symantic.Expr
index 33d8646ad751cefe7e0e04326a395d86a01c772a..83b28f7423d06ad38e269a4751d3abfaf74b8156 100644 (file)
@@ -144,15 +144,26 @@ instance Sym_List Repr_Text where
        list l = Repr_Text $ \_p v ->
                let p' = precedence_Toplevel in
                "[" <> Text.intercalate ", " ((\(Repr_Text a) -> a p' v) Prelude.<$> l) <> "]"
-       list_filter = repr_text_app2 "list_filter"
+       list_filter  = repr_text_app2 "list_filter"
+       list_zipWith = repr_text_app3 "list_zipWith"
+       list_reverse = repr_text_app1 "list_reverse"
 instance Sym_Tuple2 Repr_Text where
        tuple2 (Repr_Text a) (Repr_Text b) =
                Repr_Text $ \_p v ->
                        let p' = precedence_Toplevel in
                        "(" <> a p' v <> ", " <> b p' v <> ")"
+       fst = repr_text_app1 "fst"
+       snd = repr_text_app1 "snd"
 instance Sym_Map Repr_Text where
-       map_from_list = repr_text_app1 "map_from_list"
-       mapWithKey    = repr_text_app2 "mapWithKey"
+       map_from_list    = repr_text_app1 "map_from_list"
+       mapWithKey       = repr_text_app2 "mapWithKey"
+       map_lookup       = repr_text_app2 "map_lookup"
+       map_keys         = repr_text_app1 "map_keys"
+       map_member       = repr_text_app2 "map_member"
+       map_insert       = repr_text_app3 "map_insert"
+       map_delete       = repr_text_app2 "map_delete"
+       map_difference   = repr_text_app2 "map_difference"
+       map_foldrWithKey = repr_text_app3 "map_foldrWithKey"
 instance Sym_Functor Repr_Text where
        fmap = repr_text_app2 "fmap"
 instance Sym_Applicative Repr_Text where
index d1c7b3d9b41d5c6070af87139d3afc2918fc419e..896edae4d4fa6aac8187c1feb1281c7ba7c2c53c 100644 (file)
@@ -15,6 +15,7 @@ import qualified Expr.List.Test as List.Test
 import qualified Expr.Functor.Test as Functor.Test
 import qualified Expr.Applicative.Test as Applicative.Test
 import qualified Expr.Foldable.Test as Foldable.Test
+import qualified Expr.Map.Test as Map.Test
 
 tests :: TestTree
 tests = testGroup "Text" $
@@ -38,7 +39,7 @@ tests = testGroup "Text" $
         , Lambda.Test.e3 ==> "let x0 = True in x0 && x0"
         , Lambda.Test.e4 ==> "let x0 = \\x1 -> x1 && x1 in x0 True"
         , Lambda.Test.e5 ==> "\\x0 -> (\\x1 -> x0 && x1)"
-        , Lambda.Test.e6 ==> "(let x0 = True in x0) && False"
+        , Lambda.Test.e6 ==> "(let x0 = True in (\\x1 -> x1) x0) && False"
         , Lambda.Test.e7 ==> "\\x0 -> x0 True && True"
         , Lambda.Test.e8 ==> "\\x0 -> x0 (True && True)"
         ]
@@ -66,4 +67,7 @@ tests = testGroup "Text" $
  , testGroup "Foldable"
         [ Foldable.Test.e1 ==> "foldMap (\\x0 -> [x0, x0]) [1, 2, 3]"
         ]
+ , testGroup "Map"
+        [ Map.Test.e1 ==> "map_from_list (list_zipWith (\\x0 -> (\\x1 -> (x0, x1))) [1, 2, 3, 4, 5] [\"a\", \"b\", \"c\", \"d\", \"e\"])"
+        ]
  ]
index 09920955c2421a78ecb42cc22dd50a41fa5006e7..262435f6360fb726fbe8d4167f8215357887e21d 100644 (file)
@@ -18,12 +18,14 @@ type Type_Bool = Type_Type0 (Proxy Bool)
 pattern Type_Bool :: Type_Bool root Bool
 pattern Type_Bool  = Type_Type0 Proxy
 
-instance -- String_from_Type
- String_from_Type (Type_Bool root) where
+instance Constraint_Type Eq (Type_Bool root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Ord (Type_Bool root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Monoid (Type_Bool root)
+instance String_from_Type (Type_Bool root) where
        string_from_type _ = "Bool"
 
 -- | Inject 'Type_Bool' within a root type.
 type_bool :: Lift_Type_Root Type_Bool root => root Bool
 type_bool = type_type0
-
-instance Constraint_Type Monoid (Type_Bool root)
index 619cf9d8845f8e86508a05b980bb326c167696ac..c6175a6009c05070beea45b07187b3c2fff45d5b 100644 (file)
@@ -18,14 +18,12 @@ import Language.Symantic.Type.Type2
 -- | The 'Either' type.
 type Type_Either = Type_Type2 (Proxy Either)
 
-type instance Constraint2_of (Proxy Either)
- = Constraint2_Empty
-instance Unlift_Type1 (Type_Type2 (Proxy Either)) where
+instance Unlift_Type1 Type_Either where
        unlift_type1 (Type_Type2 px a b) k =
                k ( Type_Type1 (Proxy::Proxy (Either a)) b
                  , Lift_Type1 (\(Type_Type1 _ b') -> Type_Type2 px a b')
                  )
-instance Eq_Type root => Eq_Type1 (Type_Type2 (Proxy Either) root) where
+instance Eq_Type root => Eq_Type1 (Type_Either root) where
        eq_type1 (Type_Type2 _ a1 _b1) (Type_Type2 _ a2 _b2)
         | Just Refl <- eq_type a1 a2
         = Just Refl
index 3f993f0f7ae82fcfd9203c6ed427626425a4d037..a369ed5099c3cd8c29d25e062144774dcd01a1ac 100644 (file)
@@ -20,33 +20,32 @@ import Language.Symantic.Type.Type2
 
 -- * Type 'Type_Fun'
 -- | The @->@ type.
-type Type_Fun
- = Type_Type2 (Proxy (->))
+type Type_Fun = Type_Type2 (Proxy (->))
 
-type instance Constraint2_of (Proxy (->))
- = Constraint2_Empty
-instance Unlift_Type1 (Type_Type2 (Proxy (->))) where
+instance Unlift_Type1 Type_Fun where
        unlift_type1 (Type_Type2 px a b) k =
                k ( Type_Type1 (Proxy::Proxy ((->) a)) b
                  , Lift_Type1 (\(Type_Type1 _ b') -> Type_Type2 px a b')
                  )
-instance Eq_Type root => Eq_Type1 (Type_Type2 (Proxy (->)) root) where
+instance Eq_Type root => Eq_Type1 (Type_Fun root) where
        eq_type1 (Type_Type2 _ a1 _b1) (Type_Type2 _ a2 _b2)
         | Just Refl <- eq_type a1 a2
         = Just Refl
        eq_type1 _ _ = Nothing
+instance Constraint_Type Eq (Type_Fun root) where
+       constraint_type _c _ = Nothing
+instance Constraint_Type Ord (Type_Fun root) where
+       constraint_type _c _ = Nothing
 instance
  Constraint_Type Monoid root =>
- Constraint_Type Monoid (Type_Type2 (Proxy (->)) root) where
+ Constraint_Type Monoid (Type_Fun root) where
        constraint_type c (Type_Type2 _ _arg res)
         | Just Dict <- constraint_type c res
         = Just Dict
        constraint_type _c _ = Nothing
-instance (Constraint_Type1 Functor root)
- => Constraint_Type1 Functor (Type_Type2 (Proxy (->)) root) where
+instance Constraint_Type1 Functor (Type_Fun root) where
        constraint_type1 _c Type_Type2{} = Just Dict
-instance (Constraint_Type1 Applicative root)
- => Constraint_Type1 Applicative (Type_Type2 (Proxy (->)) root) where
+instance Constraint_Type1 Applicative (Type_Fun root) where
        constraint_type1 _c Type_Type2{} = Just Dict
 instance Constraint_Type1 Foldable (Type_Fun root)
 instance Constraint_Type1 Traversable (Type_Fun root)
@@ -61,7 +60,7 @@ pattern Type_Fun arg res
 
 instance -- Eq_Type
  Eq_Type root =>
- Eq_Type (Type_Type2 (Proxy (->)) root) where
+ Eq_Type (Type_Fun root) where
        eq_type
         (Type_Type2 _ arg1 res1)
         (Type_Type2 _ arg2 res2)
index 90772c8497db6e47afa25a0ff8bfed43e2edd21f..65fc90f3fc26e1dfae8534109f0dce40f216a7ad 100644 (file)
@@ -18,12 +18,14 @@ type Type_Int = Type_Type0 (Proxy Int)
 pattern Type_Int :: Type_Type0 (Proxy Int) root Int
 pattern Type_Int  = Type_Type0 Proxy
 
-instance -- String_from_Type
- String_from_Type (Type_Int root) where
+instance Constraint_Type Eq (Type_Int root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Ord (Type_Int root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Monoid (Type_Int root)
+instance String_from_Type (Type_Int root) where
        string_from_type _ = "Int"
 
 -- | Inject 'Type_Int' within a root type.
 type_int :: Lift_Type_Root Type_Int root => root Int
 type_int = type_type0
-
-instance Constraint_Type Monoid (Type_Int root)
index d5e1f799fb498015fd208d8785cd382861884786..68e96d331bee39b7abeba5e36863dfd86babc633 100644 (file)
@@ -9,32 +9,74 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Language.Symantic.Type.Map where
 
-import Data.Proxy
 import Data.Map.Strict as Map
+import Data.Proxy
+import Data.Type.Equality ((:~:)(Refl))
 
 import Language.Symantic.Type.Root
 import Language.Symantic.Type.Type0
+import Language.Symantic.Type.Type1
 import Language.Symantic.Type.Type2
 
 -- * Type 'Type_Map'
 -- | The 'Map' type.
 type Type_Map = Type_Type2 (Proxy Map)
 
-type instance Constraint2_of (Proxy Map)
- = Constraint2_Map
-
-{- FIXME: Could not deduce (Ord k) arising from a pattern…
 pattern Type_Map
- :: Ord k => root k -> root a
+ :: root k -> root a
  -> Type_Type2 (Proxy Map) root (Map k a)
 pattern Type_Map k a
  = Type_Type2 Proxy k a
--}
-
--- ** Class 'Constraint2_Map'
-class Constraint2_Map k a
-instance Ord k => Constraint2_Map k a
 
+instance Unlift_Type1 Type_Map where
+       unlift_type1 (Type_Type2 px a b) k =
+               k ( Type_Type1 (Proxy::Proxy (Map a)) b
+                 , Lift_Type1 (\(Type_Type1 _ b') -> Type_Type2 px a b')
+                 )
+instance
+ Constraint_Type Eq root =>
+ Constraint_Type Eq (Type_Map root) where
+       constraint_type c (Type_Type2 _ k a)
+        | Just Dict <- constraint_type c k
+        , Just Dict <- constraint_type c a
+        = Just Dict
+       constraint_type _c _ = Nothing
+instance
+ Constraint_Type Ord root =>
+ Constraint_Type Ord (Type_Map root) where
+       constraint_type c (Type_Type2 _ k a)
+        | Just Dict <- constraint_type c k
+        , Just Dict <- constraint_type c a
+        = Just Dict
+       constraint_type _c _ = Nothing
+instance
+ Constraint_Type Ord root =>
+ Constraint_Type Monoid (Type_Map root) where
+       constraint_type _c (Type_Type2 _ k _a)
+        | Just Dict <- constraint_type (Proxy::Proxy Ord) k
+        = Just Dict
+       constraint_type _c _ = Nothing
+instance Constraint_Type1 Functor (Type_Map root) where
+       constraint_type1 _c Type_Type2{} = Just Dict
+instance Constraint_Type1 Traversable (Type_Map root) where
+       constraint_type1 _c Type_Type2{} = Just Dict
+instance Constraint_Type1 Foldable (Type_Map root) where
+       constraint_type1 _c Type_Type2{} = Just Dict
+instance -- Eq_Type
+ Eq_Type root =>
+ Eq_Type (Type_Map root) where
+       eq_type (Type_Type2 _px1 k1 a1) (Type_Type2 _px2 k2 a2)
+        | Just Refl <- k1 `eq_type` k2
+        , Just Refl <- a1 `eq_type` a2
+        = Just Refl
+       eq_type _ _ = Nothing
+instance -- Eq_Type1
+ Eq_Type root =>
+ Eq_Type1 (Type_Map root) where
+       eq_type1 (Type_Type2 _px1 k1 _a1) (Type_Type2 _px2 k2 _a2)
+        | Just Refl <- k1 `eq_type` k2
+        = Just Refl
+       eq_type1 _ _ = Nothing
 instance -- String_from_Type
  String_from_Type root =>
  String_from_Type (Type_Map root) where
@@ -45,7 +87,7 @@ instance -- String_from_Type
 -- | Inject 'Type_Map' within a root type.
 type_map
  :: forall root h_k h_a.
- (Lift_Type_Root Type_Map root, Ord h_k)
+ (Lift_Type_Root Type_Map root)
  => root h_k -> root h_a
  -> root (Map h_k h_a)
 type_map k a = lift_type_root (Type_Type2 Proxy k a
index 34b994b0301573dc730f8cace3fe5dc48645249f..f083679199834f205d19b9ded3aa5667b67ada5c 100644 (file)
@@ -16,8 +16,8 @@ import Language.Symantic.Type.Type1
 -- | The 'Maybe' type.
 type Type_Maybe = Type_Type1 (Proxy Maybe)
 
-pattern Type_Map :: root a -> Type_Maybe root (Maybe a)
-pattern Type_Map a = Type_Type1 Proxy a
+pattern Type_Maybe :: root a -> Type_Maybe root (Maybe a)
+pattern Type_Maybe a = Type_Type1 Proxy a
 
 instance Constraint_Type Eq root => Constraint_Type Eq (Type_Maybe root) where
        constraint_type c (Type_Type1 _ a)
index 9b9195b0e77b5f11341b812c4c400eb123fc38e2..a575c1517a4887569a6394b743313035d3988de3 100644 (file)
@@ -1,5 +1,6 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
@@ -16,8 +17,12 @@ type Type_Ordering = Type_Type0 (Proxy Ordering)
 pattern Type_Ordering :: Type_Ordering root Ordering
 pattern Type_Ordering  = Type_Type0 Proxy
 
-instance -- String_from_Type
- String_from_Type (Type_Ordering root) where
+instance Constraint_Type Eq (Type_Ordering root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Ord (Type_Ordering root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Monoid (Type_Ordering root)
+instance String_from_Type (Type_Ordering root) where
        string_from_type _ = "Ordering"
 
 -- | Inject 'Type_Ordering' within a root type.
index f07250f60a9ca5a8fe746ee0d50835ae9f6f277a..2cbd05a257283e6d482326088eba520f0e21ea18 100644 (file)
@@ -1,5 +1,6 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -10,6 +11,7 @@ import Data.Proxy
 import Data.Text (Text)
 import Language.Symantic.Type.Root
 import Language.Symantic.Type.Type0
+import Language.Symantic.Type.Type1
 
 -- * Type 'Type_Text'
 -- | The 'Text' type.
@@ -18,6 +20,17 @@ type Type_Text = Type_Type0 (Proxy Text)
 pattern Type_Text :: Type_Type0 (Proxy Text) root Text
 pattern Type_Text  = Type_Type0 Proxy
 
+instance Constraint_Type Eq (Type_Text root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Ord (Type_Text root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Monoid (Type_Text root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type1 Functor (Type_Text root)
+instance Constraint_Type1 Applicative (Type_Text root)
+instance Constraint_Type1 Foldable (Type_Text root)
+instance Constraint_Type1 Traversable (Type_Text root)
+instance Constraint_Type1 Monad (Type_Text root)
 instance -- String_from_Type
  String_from_Type (Type_Text root) where
        string_from_type _ = "Text"
index 87f0af6d13a06c769ce1f97db99fd9522dfe3a07..33fd2c5d18731ac869454bfbf8caaa368c02c34b 100644 (file)
@@ -1,5 +1,6 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -7,23 +8,79 @@
 module Language.Symantic.Type.Tuple where
 
 import Data.Proxy
+import Data.Type.Equality ((:~:)(Refl))
 import Language.Symantic.Type.Root
 import Language.Symantic.Type.Type0
+import Language.Symantic.Type.Type1
 import Language.Symantic.Type.Type2
 
 -- * Type 'Type_Tuple2'
 -- | The @(,)@ type.
 type Type_Tuple2 = Type_Type2 (Proxy (,))
 
-type instance Constraint2_of (Proxy (,))
- = Constraint2_Empty
-
 pattern Type_Tuple2
  :: root a -> root b
  -> Type_Tuple2 root ((,) a b)
 pattern Type_Tuple2 a b
  = Type_Type2 Proxy a b
 
+instance Unlift_Type1 Type_Tuple2 where
+       unlift_type1 (Type_Type2 px a b) k =
+               k ( Type_Type1 (Proxy::Proxy ((,) a)) b
+                 , Lift_Type1 (\(Type_Type1 _ b') -> Type_Type2 px a b')
+                 )
+instance
+ Constraint_Type Eq root =>
+ Constraint_Type Eq (Type_Tuple2 root) where
+       constraint_type c (Type_Type2 _ a b)
+        | Just Dict <- constraint_type c a
+        , Just Dict <- constraint_type c b
+        = Just Dict
+       constraint_type _c _ = Nothing
+instance
+ Constraint_Type Ord root =>
+ Constraint_Type Ord (Type_Tuple2 root) where
+       constraint_type c (Type_Type2 _ a b)
+        | Just Dict <- constraint_type c a
+        , Just Dict <- constraint_type c b
+        = Just Dict
+       constraint_type _c _ = Nothing
+instance Constraint_Type1 Functor (Type_Tuple2 root) where
+       constraint_type1 _c Type_Type2{} = Just Dict
+instance
+ Constraint_Type Monoid root =>
+ Constraint_Type1 Applicative (Type_Tuple2 root) where
+       constraint_type1 _c (Type_Type2 _ a _b)
+        | Just Dict <- constraint_type (Proxy::Proxy Monoid) a
+        = Just Dict
+       constraint_type1 _c _ = Nothing
+instance Constraint_Type1 Foldable (Type_Tuple2 root) where
+       constraint_type1 _c Type_Type2{} = Just Dict
+instance Constraint_Type1 Traversable (Type_Tuple2 root) where
+       constraint_type1 _c Type_Type2{} = Just Dict
+instance
+ Constraint_Type Monoid root =>
+ Constraint_Type Monoid (Type_Tuple2 root) where
+       constraint_type c (Type_Type2 _ a b)
+        | Just Dict <- constraint_type c a
+        , Just Dict <- constraint_type c b
+        = Just Dict
+       constraint_type _c _ = Nothing
+instance -- Eq_Type
+ Eq_Type root =>
+ Eq_Type (Type_Tuple2 root) where
+       eq_type (Type_Type2 _px1 a1 b1) (Type_Type2 _px2 a2 b2)
+        | Just Refl <- a1 `eq_type` a2
+        , Just Refl <- b1 `eq_type` b2
+        = Just Refl
+       eq_type _ _ = Nothing
+instance -- Eq_Type1
+ Eq_Type root =>
+ Eq_Type1 (Type_Tuple2 root) where
+       eq_type1 (Type_Type2 _px1 a1 _b1) (Type_Type2 _px2 a2 _b2)
+        | Just Refl <- a1 `eq_type` a2
+        = Just Refl
+       eq_type1 _ _ = Nothing
 instance -- String_from_Type
  String_from_Type root =>
  String_from_Type (Type_Tuple2 root) where
index 031b2bab77261358f51a5041bc7bd36819500210..559c8b3be508b8ce71a74cfa77f3dc0cb69ec2e5 100644 (file)
@@ -178,10 +178,6 @@ instance -- Show
  String_from_Type (Type_Type0 (Proxy h0) root) =>
  Show (Type_Type0 (Proxy h0) root h0) where
        show = string_from_type
-instance Eq h0 => Constraint_Type Eq (Type_Type0 (Proxy h0) root) where
-       constraint_type _c Type_Type0{} = Just Dict
-instance Ord h0 => Constraint_Type Ord (Type_Type0 (Proxy h0) root) where
-       constraint_type _c Type_Type0{} = Just Dict
 
 -- | Convenient alias to include a 'Type_Type0' within a type.
 type_type0 :: forall root h0. Lift_Type_Root (Type_Type0 (Proxy h0)) root => root h0
index ed1ff778b20cbeb21a2ff93a9c0634f1325781e9..ac4efa5c13cd5ee7288972f3bf89d75ccfcda2af 100644 (file)
@@ -107,6 +107,7 @@ instance -- Type_Alt
  ) => Constraint_Type1 c (Type_Alt curr next root) where
        constraint_type1 c (Type_Alt_Curr ty) = constraint_type1 c ty
        constraint_type1 c (Type_Alt_Next ty) = constraint_type1 c ty
+instance Constraint_Type1 c (Type_Type0 px root)
 
 -- * Class 'Type1_from'
 -- | Parse given @ast@ into a 'Root_of_Type' constructor,
index ccb1bb8bfc3b751fa0fd2cc8ff441ba931429eda..1b18d0bb03be1516d7aaa5c6d3d47806ae70f615 100644 (file)
@@ -9,7 +9,6 @@ module Language.Symantic.Type.Type2 where
 import Data.Maybe (isJust)
 import Data.Proxy
 import Data.Type.Equality ((:~:)(Refl))
-import GHC.Prim (Constraint)
 
 import Language.Symantic.Lib.Data.Peano
 -- import Language.Symantic.Lib.Data.Bool
@@ -22,11 +21,8 @@ import Language.Symantic.Type.Type0
 -- * Type 'Type_Type2'
 data Type_Type2 px (root:: * -> *) h where
        Type_Type2
-        :: (Constraint2_of px) a b
-        => px -> root a -> root b
+        :: px -> root a -> root b
         -> Type_Type2 px root ((Host2_of px) a b)
-class Constraint2_Empty a b
-instance Constraint2_Empty a b
 
 type instance Root_of_Type      (Type_Type2 px root) = root
 type instance Error_of_Type ast (Type_Type2 px root) = No_Error_Type
@@ -64,14 +60,7 @@ instance -- Show
  , String_from_Type (Type_Type2 px root)
  ) => Show (Type_Type2 px root h) where
        show = string_from_type
-instance Constraint_Type Eq  (Type_Type2 px root)
-instance Constraint_Type Ord (Type_Type2 px root)
--- instance Unlift_Type1 (Type_Type2 px)  -- NOTE: done case by case
--- instance Eq_Type1 (Type_Type2 px root) -- FIXME: should be doable
 
 -- ** Type 'Host2_of'
 type family Host2_of px :: * -> * -> *
 type instance Host2_of (Proxy h2) = h2
-
--- ** Type 'Constraint2_of'
-type family Constraint2_of px :: (* -> * -> Constraint)
index 067e3f62474329e9fa04ddd3da01affbb807c463..8f014eb88797b7cebb5d1176669845ba7f7dd79e 100644 (file)
@@ -1,5 +1,6 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -18,6 +19,11 @@ type Type_Unit = Type_Type0 (Proxy ())
 pattern Type_Unit :: Type_Unit root ()
 pattern Type_Unit  = Type_Type0 Proxy
 
+instance Constraint_Type Eq (Type_Unit root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Ord (Type_Unit root) where
+       constraint_type _c Type_Type0{} = Just Dict
+instance Constraint_Type Monoid (Type_Unit root)
 instance -- String_from_Type
  String_from_Type (Type_Unit root) where
        string_from_type _ = "()"
index 24ecb6127eca12a13e800002f3945e6793c42127..b30eba7ebc4a68fa06c163916d81b32bf2977235 100644 (file)
@@ -41,10 +41,9 @@ description:
  and then interpret them at will.
  .
  One important drawback of this flexibility
- is the introduction of a lot of type constraints,
- so far this hasn't discouraged me… because for this
- reading the vertically-aligned source code is easier
- than its Haddock rendition.
+ is the introduction of a lot of type constraints;
+ those may be more readable directly in the source code
+ than in its Haddock rendition.
  .
  Your comments, problem reports, or questions are very welcome! :-)
  .
@@ -185,6 +184,7 @@ Test-Suite symantic-test
     Expr.Int.Test
     Expr.Lambda.Test
     Expr.List.Test
+    Expr.Map.Test
     Expr.Maybe.Test
     Expr.Monad.Test
     Expr.Test
@@ -206,6 +206,7 @@ Test-Suite symantic-test
     ghc-options: -fprof-auto
   build-depends:
     base >= 4.6 && < 5
+    , containers
     , transformers
     , tasty >= 0.11
     , tasty-hunit