]> Git — Sourcephile - haskell/symantic.git/blob - Language/Symantic/Expr/Ord.hs
init
[haskell/symantic.git] / Language / Symantic / Expr / Ord.hs
1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE ScopedTypeVariables #-}
4 {-# LANGUAGE TypeFamilies #-}
5 -- | Expression for 'Ord'.
6 module Language.Symantic.Expr.Ord where
7
8 import Data.Proxy (Proxy(..))
9 import Data.Type.Equality ((:~:)(Refl))
10 import Prelude hiding (compare)
11
12 import Language.Symantic.Repr.Dup
13 import Language.Symantic.Trans.Common
14 import Language.Symantic.Type
15 import Language.Symantic.Expr.Common
16 import Language.Symantic.Expr.Lambda
17 import Language.Symantic.Expr.Bool
18 import Language.Symantic.Expr.Eq
19
20 -- * Class 'Sym_Ord'
21 -- | Symantic.
22 class Sym_Eq repr => Sym_Ord repr where
23 compare :: Ord a => repr a -> repr a -> repr Ordering
24 default compare :: (Trans t repr, Ord a)
25 => t repr a -> t repr a -> t repr Ordering
26 compare = trans_map2 compare
27
28 instance (Sym_Ord r1, Sym_Ord r2) => Sym_Ord (Dup r1 r2) where
29 compare (x1 `Dup` x2) (y1 `Dup` y2) =
30 compare x1 y1 `Dup`
31 compare x2 y2
32
33 -- * Type 'Expr_Ord'
34 -- | Expression.
35 data Expr_Ord (root:: *)
36 type instance Root_of_Expr (Expr_Ord root) = root
37 type instance Type_of_Expr (Expr_Ord root) = No_Type
38 type instance Sym_of_Expr (Expr_Ord root) repr = (Sym_Ord repr)
39 type instance Error_of_Expr ast (Expr_Ord root) = No_Error_Expr
40
41 ord_from
42 :: forall root ty ast hs ret.
43 ( ty ~ Type_Root_of_Expr (Expr_Ord root)
44 , Type_Root_Lift Type_Bool (Type_Root_of_Expr root)
45 , Type_Root_Lift Type_Ordering (Type_Root_of_Expr root)
46 , Type_Eq (Type_Root_of_Expr root)
47 , Expr_from ast root
48 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
49 (Error_of_Expr ast root)
50 , Root_of_Expr root ~ root
51 , Type_Constraint Ord ty
52 ) => ast -> ast
53 -> Expr_From ast (Expr_Ord root) hs ret
54 ord_from ast_x ast_y ex ast ctx k =
55 expr_from (Proxy::Proxy root) ast_x ctx $
56 \(ty_x::Type_Root_of_Expr root h_x) (Forall_Repr_with_Context x) ->
57 expr_from (Proxy::Proxy root) ast_y ctx $
58 \(ty_y::Type_Root_of_Expr root h_y) (Forall_Repr_with_Context y) ->
59 when_type_eq ex ast ty_x ty_y $ \Refl ->
60 when_type_constraint ex (Proxy::Proxy Ord) ast ty_x $ \Dict ->
61 k type_ordering $ Forall_Repr_with_Context $
62 \c -> x c `compare` y c
63
64 -- ** Type 'Expr_Lambda_Bool_Ord'
65 -- | Convenient alias.
66 type Expr_Lambda_Bool_Ord lam
67 = Expr_Root (Expr_Alt (Expr_Lambda lam)
68 (Expr_Alt Expr_Bool
69 Expr_Ord))
70
71 -- | Convenient alias around 'expr_from'.
72 expr_lambda_bool_ord_from
73 :: forall lam ast.
74 Expr_from ast (Expr_Lambda_Bool_Ord lam)
75 => Proxy lam
76 -> ast
77 -> Either (Error_of_Expr ast (Expr_Lambda_Bool_Ord lam))
78 (Exists_Type_and_Repr (Type_Root_of_Expr (Expr_Lambda_Bool_Ord lam))
79 (Forall_Repr (Expr_Lambda_Bool_Ord lam)))
80 expr_lambda_bool_ord_from _lam ast =
81 expr_from (Proxy::Proxy (Expr_Lambda_Bool_Ord lam)) ast
82 Context_Empty $ \ty (Forall_Repr_with_Context repr) ->
83 Right $ Exists_Type_and_Repr ty $
84 Forall_Repr $ repr Context_Empty