{-# LANGUAGE OverloadedStrings #-}

module Hydra.Impl.Haskell.Sources.Phantoms where

import Hydra.Kernel
import Hydra.Impl.Haskell.Dsl.Types as Types
import Hydra.Impl.Haskell.Dsl.Standard
import Hydra.Impl.Haskell.Sources.Core
import Hydra.Impl.Haskell.Sources.Compute


hydraPhantomsModule :: Module Meta
hydraPhantomsModule :: Module Meta
hydraPhantomsModule = forall m.
Namespace -> [Element m] -> [Module m] -> Maybe String -> Module m
Module Namespace
ns [Element Meta]
elements [Module Meta
hydraComputeModule] forall a b. (a -> b) -> a -> b
$
    forall a. a -> Maybe a
Just String
"Phantom types for use in model definitions"
  where
    ns :: Namespace
ns = String -> Namespace
Namespace String
"hydra/phantoms"
    core :: String -> Type m
core = forall m. Namespace -> String -> Type m
nsref forall a b. (a -> b) -> a -> b
$ forall m. Module m -> Namespace
moduleNamespace Module Meta
hydraCoreModule
    evaluation :: String -> Type m
evaluation = forall m. Namespace -> String -> Type m
nsref forall a b. (a -> b) -> a -> b
$ forall m. Module m -> Namespace
moduleNamespace Module Meta
hydraComputeModule
    phantoms :: String -> Type m
phantoms = forall m. Namespace -> String -> Type m
nsref Namespace
ns
    def :: String -> Type m -> Element m
def = forall m. Namespace -> String -> Type m -> Element m
datatype Namespace
ns

    elements :: [Element Meta]
elements = [
      forall {m}. String -> Type m -> Element m
def String
"Case" forall a b. (a -> b) -> a -> b
$
        String -> Type Meta -> Type Meta
doc String
"An association of a field name (as in a case statement) with a phantom type" forall a b. (a -> b) -> a -> b
$
        forall m. String -> Type m -> Type m
lambda String
"a" forall a b. (a -> b) -> a -> b
$ forall {m}. String -> Type m
core String
"FieldName",

      forall {m}. String -> Type m -> Element m
def String
"Datum" forall a b. (a -> b) -> a -> b
$
        String -> Type Meta -> Type Meta
doc String
"An association of a term with a phantom type" forall a b. (a -> b) -> a -> b
$
        forall m. String -> Type m -> Type m
lambda String
"a" forall a b. (a -> b) -> a -> b
$ (forall {m}. String -> Type m
core String
"Term") forall m. Type m -> Type m -> Type m
@@ (forall {m}. String -> Type m
evaluation String
"Meta"),

      forall {m}. String -> Type m -> Element m
def String
"Definition" forall a b. (a -> b) -> a -> b
$
        String -> Type Meta -> Type Meta
doc String
"An association with a named term with a phantom type" forall a b. (a -> b) -> a -> b
$
        forall m. String -> Type m -> Type m
lambda String
"a" forall a b. (a -> b) -> a -> b
$ forall m. [FieldType m] -> Type m
record [
          String
"name"forall m. String -> Type m -> FieldType m
>: forall {m}. String -> Type m
core String
"Name",
          String
"datum"forall m. String -> Type m -> FieldType m
>: forall {m}. String -> Type m
phantoms String
"Datum" forall m. Type m -> Type m -> Type m
@@ Type Meta
"a"],

      forall {m}. String -> Type m -> Element m
def String
"Fld" forall a b. (a -> b) -> a -> b
$
        String -> Type Meta -> Type Meta
doc String
"An association with a term-level field with a phantom type" forall a b. (a -> b) -> a -> b
$
        forall m. String -> Type m -> Type m
lambda String
"a" forall a b. (a -> b) -> a -> b
$ (forall {m}. String -> Type m
core String
"Field") forall m. Type m -> Type m -> Type m
@@ (forall {m}. String -> Type m
evaluation String
"Meta"),

      forall {m}. String -> Type m -> Element m
def String
"Reference" forall a b. (a -> b) -> a -> b
$
        String -> Type Meta -> Type Meta
doc String
"A pure association with a phantom type" forall a b. (a -> b) -> a -> b
$
        forall m. String -> Type m -> Type m
lambda String
"a" forall a b. (a -> b) -> a -> b
$ forall m. Type m
unit]