1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE DefaultSignatures #-}
4 {-# LANGUAGE MultiParamTypeClasses #-}
5 {-# LANGUAGE NoMonomorphismRestriction #-}
6 {-# LANGUAGE ScopedTypeVariables #-}
7 {-# LANGUAGE TypeApplications #-}
8 {-# LANGUAGE TypeFamilies #-}
9 {-# LANGUAGE NoImplicitPrelude #-}
10 module Symantic.Typed.Lang where
12 import Data.Char (Char)
13 import Data.Bool (Bool(..))
14 import Data.Either (Either(..))
16 import Data.Maybe (Maybe(..))
17 import qualified Data.Function as Fun
19 import Symantic.Typed.Transformable
21 -- * Class 'Abstractable'
22 class Abstractable repr where
23 -- | Application, aka. unabstract.
24 (.@) :: repr (a->b) -> repr a -> repr b; infixl 9 .@
25 -- | Lambda term abstraction, in HOAS (Higher-Order Abstract Syntax) style.
26 lam :: (repr a -> repr b) -> repr (a->b)
27 -- | Like 'lam' but whose argument is used only once,
28 -- hence safe to beta-reduce (inline) without duplicating work.
29 lam1 :: (repr a -> repr b) -> repr (a->b)
30 const :: repr (a -> b -> a)
31 flip :: repr ((a -> b -> c) -> b -> a -> c)
33 (.) :: repr ((b->c) -> (a->b) -> a -> c); infixr 9 .
34 ($) :: repr ((a->b) -> a -> b); infixr 0 $
35 var :: repr a -> repr a
36 (.@) = liftDerived2 (.@)
37 lam f = liftDerived (lam (derive Fun.. f Fun.. liftDerived))
38 lam1 f = liftDerived (lam1 (derive Fun.. f Fun.. liftDerived))
39 const = liftDerived const
40 flip = liftDerived flip
44 var = liftDerived1 var
46 FromDerived2 Abstractable repr =>
47 repr (a->b) -> repr a -> repr b
49 FromDerived Abstractable repr => Derive repr =>
50 (repr a -> repr b) -> repr (a->b)
52 FromDerived Abstractable repr => Derive repr =>
53 (repr a -> repr b) -> repr (a->b)
55 FromDerived Abstractable repr =>
58 FromDerived Abstractable repr =>
59 repr ((a -> b -> c) -> b -> a -> c)
61 FromDerived Abstractable repr =>
64 FromDerived Abstractable repr =>
65 repr ((b->c) -> (a->b) -> a -> c)
67 FromDerived Abstractable repr =>
68 repr ((a->b) -> a -> b)
70 FromDerived1 Abstractable repr =>
73 -- * Class 'Anythingable'
74 class Anythingable repr where
75 anything :: repr a -> repr a
78 -- * Class 'Constantable'
79 class Constantable c repr where
80 constant :: c -> repr c
81 constant = liftDerived Fun.. constant
83 FromDerived (Constantable c) repr =>
86 bool :: Constantable Bool repr => Bool -> repr Bool
88 char :: Constantable Char repr => Char -> repr Char
90 unit :: Constantable () repr => repr ()
91 unit = constant @() ()
93 -- * Class 'Eitherable'
94 class Eitherable repr where
95 left :: repr (l -> Either l r)
96 right :: repr (r -> Either l r)
97 left = liftDerived left
98 right = liftDerived right
100 FromDerived Eitherable repr =>
101 repr (l -> Either l r)
103 FromDerived Eitherable repr =>
104 repr (r -> Either l r)
106 -- * Class 'Equalable'
107 class Equalable repr where
108 equal :: Eq a => repr (a -> a -> Bool)
109 equal = liftDerived equal
111 FromDerived Equalable repr =>
112 Eq a => repr (a -> a -> Bool)
115 (==) :: (Abstractable repr, Equalable repr, Eq a) => repr (a -> a -> Bool)
116 (==) = lam (\x -> lam (\y -> equal .@ x .@ y))
118 -- * Class 'IfThenElseable'
119 class IfThenElseable repr where
120 ifThenElse :: repr Bool -> repr a -> repr a -> repr a
121 ifThenElse = liftDerived3 ifThenElse
122 default ifThenElse ::
123 FromDerived3 IfThenElseable repr =>
124 repr Bool -> repr a -> repr a -> repr a
126 -- * Class 'Listable'
127 class Listable repr where
128 cons :: repr (a -> [a] -> [a])
130 cons = liftDerived cons
131 nil = liftDerived nil
133 FromDerived Listable repr =>
134 repr (a -> [a] -> [a])
136 FromDerived Listable repr =>
139 -- * Class 'Maybeable'
140 class Maybeable repr where
141 nothing :: repr (Maybe a)
142 just :: repr (a -> Maybe a)
143 nothing = liftDerived nothing
144 just = liftDerived just
146 FromDerived Maybeable repr =>
149 FromDerived Maybeable repr =>