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.Functor (Functor (..))
20 import Data.Kind (Type)
21 import Text.Show (Show (..))
22 import Unsafe.Coerce (unsafeCoerce)
23 import qualified Data.Function as Fun
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
33 ) => Functor (Forall syns) where
34 fmap f (Forall sem) = Forall (fmap f sem)
35 a <$ (Forall sem) = Forall (a <$ sem)
37 ( forall sem. Syntaxes syns sem => Applicative sem
38 , Functor (Forall syns)
39 ) => Applicative (Forall syns) where
40 pure a = Forall (pure a)
41 liftA2 f (Forall a) (Forall b) = Forall (liftA2 f a b)
42 (<*>) (Forall f) (Forall a) = Forall ((<*>) f a)
43 (<*) (Forall f) (Forall a) = Forall ((<*) f a)
44 (*>) (Forall f) (Forall a) = Forall ((*>) f a)
46 ( forall sem. Syntaxes syns sem => Monad sem
47 , Applicative (Forall syns)
48 ) => Monad (Forall syns) where
49 (>>=) (Forall sa) f = Forall (sa >>= \a -> case f a of Forall sb -> sb)
53 (forall sem. Syntaxes syns sem => Instantiable sem) =>
54 Instantiable (Forall syns)
56 Forall a2b .@ Forall a = Forall (a2b .@ a)
58 ( forall sem. Syntaxes syns sem => Abstractable sem
59 , forall sem. Syntaxes syns sem => Instantiable sem
60 ) => Abstractable (Forall syns) where
61 lam f = Forall (lam (\a -> let Forall b = f (forallSem a) in b))
63 -- Safe here because (a :: sem a) and (b :: sem b) share the same 'sem'.
64 forallSem :: sem a -> Forall syns a
65 forallSem a = Forall (unsafeCoerce a)
67 ( forall sem. Syntaxes syns sem => Unabstractable sem
68 ) => Unabstractable (Forall syns) where
77 data PerSyntax :: [Syntax] -> (Syntax -> Type) -> Type where
78 PerSyntaxZ :: a syn -> PerSyntax (syn ': syns) a
79 PerSyntaxS :: PerSyntax syns a -> PerSyntax (skipSyn ': syns) a
81 instance Eq (PerSyntax '[] a) where
85 , Eq (PerSyntax syns a)
87 Eq (PerSyntax (syn ': syns) a)
89 PerSyntaxZ x == PerSyntaxZ y = x == y
90 PerSyntaxS x == PerSyntaxS y = x == y
93 instance Show (PerSyntax '[] a) where
94 showsPrec _p = \case {}
97 , Show (PerSyntax syns a)
99 Show (PerSyntax (syn ': syns) a)
102 PerSyntaxZ a -> showsPrec p a
103 PerSyntaxS s -> showsPrec p s
105 -- ** Class 'PerSyntaxable'
106 class PerSyntaxable (syns :: [Syntax]) (syn :: Syntax) where
107 perSyntax :: a syn -> PerSyntax syns a
108 instance {-# OVERLAPS #-} PerSyntaxable (syn ': syns) syn where
109 perSyntax = PerSyntaxZ
110 instance PerSyntaxable syns syn => PerSyntaxable (skipSyn ': syns) syn where
111 perSyntax = PerSyntaxS Fun.. perSyntax