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, 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 => Unabstractable sem) =>
60 Unabstractable (Forall syns)
62 Forall a2b .@ Forall a = Forall (a2b .@ a)
64 ( forall sem. Syntaxes syns sem => Abstractable sem
65 , forall sem. Syntaxes syns sem => Unabstractable sem
67 Abstractable (Forall syns)
69 lam f = Forall (lam (\a -> let Forall b = f (forallSem a) in b))
71 -- Safe here because (a :: sem a) and (b :: sem b) share the same 'sem'.
72 forallSem :: sem a -> Forall syns a
73 forallSem a = Forall (unsafeCoerce a)
76 data PerSyntax :: [Syntax] -> (Syntax -> Type) -> Type where
77 PerSyntaxZ :: a syn -> PerSyntax (syn ': syns) a
78 PerSyntaxS :: PerSyntax syns a -> PerSyntax (skipSyn ': syns) a
80 instance Eq (PerSyntax '[] a) where
84 , Eq (PerSyntax syns a)
86 Eq (PerSyntax (syn ': syns) a)
88 PerSyntaxZ x == PerSyntaxZ y = x == y
89 PerSyntaxS x == PerSyntaxS y = x == y
92 instance Show (PerSyntax '[] a) where
93 showsPrec _p = \case {}
96 , Show (PerSyntax syns a)
98 Show (PerSyntax (syn ': syns) a)
101 PerSyntaxZ a -> showsPrec p a
102 PerSyntaxS s -> showsPrec p s
104 -- ** Class 'PerSyntaxable'
105 class PerSyntaxable (syns :: [Syntax]) (syn :: Syntax) where
106 perSyntax :: a syn -> PerSyntax syns a
107 instance {-# OVERLAPS #-} PerSyntaxable (syn ': syns) syn where
108 perSyntax = PerSyntaxZ
109 instance PerSyntaxable syns syn => PerSyntaxable (skipSyn ': syns) syn where
110 perSyntax = PerSyntaxS . perSyntax