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.Univariant.Lang where
12 import Data.Char (Char)
13 import Data.Bool (Bool(..))
14 import Data.Either (Either(..))
17 import Data.Maybe (Maybe(..))
18 import Prelude (undefined)
19 import Text.Show (Show(..))
20 import qualified Data.Eq as Eq
21 import qualified Data.Function as Fun
22 import qualified Prelude
24 import Symantic.Univariant.Trans
26 class Abstractable repr where
27 -- | Application, aka. unabstract.
28 (.@) :: repr (a->b) -> repr a -> repr b; infixl 9 .@
29 -- | Lambda term abstraction, in HOAS (Higher-Order Abstract Syntax) style.
30 lam :: (repr a -> repr b) -> repr (a->b)
31 -- | Like 'lam' but whose argument is used only once,
32 -- hence safe to beta-reduce (inline) without duplicating work.
33 lam1 :: (repr a -> repr b) -> repr (a->b)
34 const :: repr (a -> b -> a)
35 flip :: repr ((a -> b -> c) -> b -> a -> c)
37 (.) :: repr ((b->c) -> (a->b) -> a -> c); infixr 9 .
38 ($) :: repr ((a->b) -> a -> b); infixr 0 $
39 var :: repr a -> repr a
41 Liftable2 repr => Abstractable (Output repr) =>
42 repr (a->b) -> repr a -> repr b
44 Liftable repr => Unliftable repr => Abstractable (Output repr) =>
45 (repr a -> repr b) -> repr (a->b)
47 Liftable repr => Unliftable repr => Abstractable (Output repr) =>
48 (repr a -> repr b) -> repr (a->b)
50 Liftable repr => Abstractable (Output repr) =>
53 Liftable repr => Abstractable (Output repr) =>
54 repr ((a -> b -> c) -> b -> a -> c)
56 Liftable repr => Abstractable (Output repr) =>
59 Liftable repr => Abstractable (Output repr) =>
60 repr ((b->c) -> (a->b) -> a -> c)
62 Liftable repr => Abstractable (Output repr) =>
63 repr ((a->b) -> a -> b)
65 Liftable1 repr => Abstractable (Output repr) =>
68 lam f = lift (lam (trans Fun.. f Fun.. trans))
69 lam1 f = lift (lam1 (trans Fun.. f Fun.. trans))
76 class Anythingable repr where
77 anything :: repr a -> repr a
79 class Constantable c repr where
80 constant :: c -> repr c
82 Liftable repr => Constantable c (Output repr) =>
84 constant = lift Fun.. constant
87 unit = constant @() ()
88 class Eitherable repr where
89 left :: repr (l -> Either l r)
90 right :: repr (r -> Either l r)
92 Liftable repr => Eitherable (Output repr) =>
93 repr (l -> Either l r)
95 Liftable repr => Eitherable (Output repr) =>
96 repr (r -> Either l r)
99 class Equalable repr where
100 equal :: Eq a => repr (a -> a -> Bool)
102 Liftable repr => Equalable (Output repr) =>
103 Eq a => repr (a -> a -> Bool)
106 (==) = lam (\x -> lam (\y -> equal .@ x .@ y))
107 class Listable repr where
108 cons :: repr (a -> [a] -> [a])
111 Liftable repr => Listable (Output repr) =>
112 repr (a -> [a] -> [a])
114 Liftable repr => Listable (Output repr) =>
118 class Maybeable repr where
119 nothing :: repr (Maybe a)
120 just :: repr (a -> Maybe a)
122 Liftable repr => Maybeable (Output repr) =>
125 Liftable repr => Maybeable (Output repr) =>
127 nothing = lift nothing