1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE EmptyCase #-}
4 {-# LANGUAGE QuantifiedConstraints #-}
5 {-# LANGUAGE RankNTypes #-}
6 {-# LANGUAGE UndecidableInstances #-}
8 module Symantic.Semantics.Forall where
10 import Control.Applicative (Applicative (..))
11 import Control.Monad (Monad (..))
12 import Data.Bool (Bool (..))
13 import Data.Eq (Eq (..))
14 import Data.Function ((.))
15 import Data.Functor (Functor (..))
16 import Data.Kind (Type)
17 import Text.Show (Show (..))
19 import Symantic.Syntaxes.Classes (Syntax, Syntaxes, Unabstractable (..))
22 newtype Forall (syns :: [Syntax]) (a :: Type)
23 = Forall (forall sem. Syntaxes syns sem => sem a)
26 ( forall sem. Syntaxes syns sem => Functor sem
30 fmap f (Forall sem) = Forall (fmap f sem)
31 a <$ (Forall sem) = Forall (a <$ sem)
33 ( forall sem. Syntaxes syns sem => Applicative sem
34 , Functor (Forall syns)
36 Applicative (Forall syns)
38 pure a = Forall (pure a)
39 liftA2 f (Forall a) (Forall b) = Forall (liftA2 f a b)
40 (<*>) (Forall f) (Forall a) = Forall ((<*>) f a)
41 (<*) (Forall f) (Forall a) = Forall ((<*) f a)
42 (*>) (Forall f) (Forall a) = Forall ((*>) f a)
44 ( forall sem. Syntaxes syns sem => Monad sem
45 , Applicative (Forall syns)
49 (>>=) (Forall sa) f = Forall (sa >>= \a -> case f a of Forall sb -> sb)
53 (forall sem. Syntaxes syns sem => Unabstractable sem) =>
54 Unabstractable (Forall syns)
56 Forall a2b .@ Forall a = Forall (a2b .@ a)
59 data PerSyntax :: [Syntax] -> (Syntax -> Type) -> Type where
60 PerSyntaxZ :: a syn -> PerSyntax (syn ': syns) a
61 PerSyntaxS :: PerSyntax syns a -> PerSyntax (skipSyn ': syns) a
63 instance Eq (PerSyntax '[] a) where
67 , Eq (PerSyntax syns a)
69 Eq (PerSyntax (syn ': syns) a)
71 PerSyntaxZ x == PerSyntaxZ y = x == y
72 PerSyntaxS x == PerSyntaxS y = x == y
75 instance Show (PerSyntax '[] a) where
76 showsPrec _p = \case {}
79 , Show (PerSyntax syns a)
81 Show (PerSyntax (syn ': syns) a)
84 PerSyntaxZ a -> showsPrec p a
85 PerSyntaxS s -> showsPrec p s
87 -- ** Class 'PerSyntaxable'
88 class PerSyntaxable (syns :: [Syntax]) (syn :: Syntax) where
89 perSyntax :: a syn -> PerSyntax syns a
90 instance {-# OVERLAPS #-} PerSyntaxable (syn ': syns) syn where
91 perSyntax = PerSyntaxZ
92 instance PerSyntaxable syns syn => PerSyntaxable (skipSyn ': syns) syn where
93 perSyntax = PerSyntaxS . perSyntax