1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE EmptyCase #-}
4 {-# LANGUAGE QuantifiedConstraints #-}
5 {-# LANGUAGE RankNTypes #-}
6 {-# LANGUAGE UndecidableInstances #-}
8 -- | This module provides the 'Forall' semantic
9 -- which preserves the polymorphism of the semantic.
10 -- Useful when parsing the syntax from a text
11 -- (ie. when the domain-specific language
12 -- is not embedded into a Haskell file).
13 module Symantic.Semantics.Forall where
15 import Control.Applicative (Applicative (..))
16 import Control.Monad (Monad (..))
17 import Data.Bool (Bool (..))
18 import Data.Eq (Eq (..))
19 import Data.Function ((.))
20 import Data.Functor (Functor (..))
21 import Data.Kind (Type)
22 import Text.Show (Show (..))
23 import Unsafe.Coerce (unsafeCoerce)
25 import Symantic.Syntaxes.Classes (Abstractable (..), Syntax, Syntaxes, Instantiable (..), Unabstractable (..))
28 newtype Forall (syns :: [Syntax]) (a :: Type)
29 = Forall (forall sem. Syntaxes syns sem => sem a)
32 ( forall sem. Syntaxes syns sem => Functor sem
36 fmap f (Forall sem) = Forall (fmap f sem)
37 a <$ (Forall sem) = Forall (a <$ sem)
39 ( forall sem. Syntaxes syns sem => Applicative sem
40 , Functor (Forall syns)
42 Applicative (Forall syns)
44 pure a = Forall (pure a)
45 liftA2 f (Forall a) (Forall b) = Forall (liftA2 f a b)
46 (<*>) (Forall f) (Forall a) = Forall ((<*>) f a)
47 (<*) (Forall f) (Forall a) = Forall ((<*) f a)
48 (*>) (Forall f) (Forall a) = Forall ((*>) f a)
50 ( forall sem. Syntaxes syns sem => Monad sem
51 , Applicative (Forall syns)
55 (>>=) (Forall sa) f = Forall (sa >>= \a -> case f a of Forall sb -> sb)
59 (forall sem. Syntaxes syns sem => Instantiable sem) =>
60 Instantiable (Forall syns)
62 Forall a2b .@ Forall a = Forall (a2b .@ a)
64 ( forall sem. Syntaxes syns sem => Abstractable sem
65 , forall sem. Syntaxes syns sem => Instantiable sem
66 ) => Abstractable (Forall syns) where
67 lam f = Forall (lam (\a -> let Forall b = f (forallSem a) in b))
69 -- Safe here because (a :: sem a) and (b :: sem b) share the same 'sem'.
70 forallSem :: sem a -> Forall syns a
71 forallSem a = Forall (unsafeCoerce a)
74 data PerSyntax :: [Syntax] -> (Syntax -> Type) -> Type where
75 PerSyntaxZ :: a syn -> PerSyntax (syn ': syns) a
76 PerSyntaxS :: PerSyntax syns a -> PerSyntax (skipSyn ': syns) a
78 instance Eq (PerSyntax '[] a) where
82 , Eq (PerSyntax syns a)
84 Eq (PerSyntax (syn ': syns) a)
86 PerSyntaxZ x == PerSyntaxZ y = x == y
87 PerSyntaxS x == PerSyntaxS y = x == y
90 instance Show (PerSyntax '[] a) where
91 showsPrec _p = \case {}
94 , Show (PerSyntax syns a)
96 Show (PerSyntax (syn ': syns) a)
99 PerSyntaxZ a -> showsPrec p a
100 PerSyntaxS s -> showsPrec p s
102 -- ** Class 'PerSyntaxable'
103 class PerSyntaxable (syns :: [Syntax]) (syn :: Syntax) where
104 perSyntax :: a syn -> PerSyntax syns a
105 instance {-# OVERLAPS #-} PerSyntaxable (syn ': syns) syn where
106 perSyntax = PerSyntaxZ
107 instance PerSyntaxable syns syn => PerSyntaxable (skipSyn ': syns) syn where
108 perSyntax = PerSyntaxS . perSyntax