module Language.Elm.Definition where

import Data.Void

import Bound (Scope)
import qualified Bound

import Language.Elm.Expression (Expression)
import qualified Language.Elm.Expression as Expression
import qualified Language.Elm.Name as Name
import Language.Elm.Type (Type)
import qualified Language.Elm.Type as Type

data Definition
  = Constant !Name.Qualified !Int (Scope Int Type Void) (Expression Void)
  | Type !Name.Qualified !Int [(Name.Constructor, [Scope Int Type Void])]
  | Alias !Name.Qualified !Int (Scope Int Type Void)
  deriving (Definition -> Definition -> Bool
(Definition -> Definition -> Bool)
-> (Definition -> Definition -> Bool) -> Eq Definition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Definition -> Definition -> Bool
$c/= :: Definition -> Definition -> Bool
== :: Definition -> Definition -> Bool
$c== :: Definition -> Definition -> Bool
Eq, Eq Definition
Eq Definition
-> (Definition -> Definition -> Ordering)
-> (Definition -> Definition -> Bool)
-> (Definition -> Definition -> Bool)
-> (Definition -> Definition -> Bool)
-> (Definition -> Definition -> Bool)
-> (Definition -> Definition -> Definition)
-> (Definition -> Definition -> Definition)
-> Ord Definition
Definition -> Definition -> Bool
Definition -> Definition -> Ordering
Definition -> Definition -> Definition
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Definition -> Definition -> Definition
$cmin :: Definition -> Definition -> Definition
max :: Definition -> Definition -> Definition
$cmax :: Definition -> Definition -> Definition
>= :: Definition -> Definition -> Bool
$c>= :: Definition -> Definition -> Bool
> :: Definition -> Definition -> Bool
$c> :: Definition -> Definition -> Bool
<= :: Definition -> Definition -> Bool
$c<= :: Definition -> Definition -> Bool
< :: Definition -> Definition -> Bool
$c< :: Definition -> Definition -> Bool
compare :: Definition -> Definition -> Ordering
$ccompare :: Definition -> Definition -> Ordering
$cp1Ord :: Eq Definition
Ord, Int -> Definition -> ShowS
[Definition] -> ShowS
Definition -> String
(Int -> Definition -> ShowS)
-> (Definition -> String)
-> ([Definition] -> ShowS)
-> Show Definition
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Definition] -> ShowS
$cshowList :: [Definition] -> ShowS
show :: Definition -> String
$cshow :: Definition -> String
showsPrec :: Int -> Definition -> ShowS
$cshowsPrec :: Int -> Definition -> ShowS
Show)

name :: Definition -> Name.Qualified
name :: Definition -> Qualified
name (Constant Qualified
n Int
_ Scope Int Type Void
_ Expression Void
_) = Qualified
n
name (Type Qualified
n Int
_ [(Constructor, [Scope Int Type Void])]
_) = Qualified
n
name (Alias Qualified
n Int
_ Scope Int Type Void
_) = Qualified
n

foldMapGlobals
  :: Monoid m
  => (Name.Qualified -> m)
  -> Definition
  -> m
foldMapGlobals :: (Qualified -> m) -> Definition -> m
foldMapGlobals Qualified -> m
f Definition
def =
  case Definition
def of
    Constant Qualified
qname Int
_ Scope Int Type Void
type_ Expression Void
expr ->
      Qualified -> m
f Qualified
qname m -> m -> m
forall a. Semigroup a => a -> a -> a
<>
      (Qualified -> m) -> Type (Var Int Void) -> m
forall m v. Monoid m => (Qualified -> m) -> Type v -> m
Type.foldMapGlobals Qualified -> m
f (Scope Int Type Void -> Type (Var Int Void)
forall (f :: * -> *) b a. Monad f => Scope b f a -> f (Var b a)
Bound.fromScope Scope Int Type Void
type_) m -> m -> m
forall a. Semigroup a => a -> a -> a
<>
      (Qualified -> m) -> Expression Void -> m
forall m v. Monoid m => (Qualified -> m) -> Expression v -> m
Expression.foldMapGlobals Qualified -> m
f Expression Void
expr

    Type Qualified
qname Int
_ [(Constructor, [Scope Int Type Void])]
constrs ->
      Qualified -> m
f Qualified
qname m -> m -> m
forall a. Semigroup a => a -> a -> a
<>
      ((Constructor, [Scope Int Type Void]) -> m)
-> [(Constructor, [Scope Int Type Void])] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (([Scope Int Type Void] -> m)
-> (Constructor, [Scope Int Type Void]) -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Scope Int Type Void -> m) -> [Scope Int Type Void] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Qualified -> m) -> Type (Var Int Void) -> m
forall m v. Monoid m => (Qualified -> m) -> Type v -> m
Type.foldMapGlobals Qualified -> m
f (Type (Var Int Void) -> m)
-> (Scope Int Type Void -> Type (Var Int Void))
-> Scope Int Type Void
-> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scope Int Type Void -> Type (Var Int Void)
forall (f :: * -> *) b a. Monad f => Scope b f a -> f (Var b a)
Bound.fromScope))) [(Constructor, [Scope Int Type Void])]
constrs

    Alias Qualified
qname Int
_ Scope Int Type Void
type_ ->
      Qualified -> m
f Qualified
qname m -> m -> m
forall a. Semigroup a => a -> a -> a
<>
      (Qualified -> m) -> Type (Var Int Void) -> m
forall m v. Monoid m => (Qualified -> m) -> Type v -> m
Type.foldMapGlobals Qualified -> m
f (Scope Int Type Void -> Type (Var Int Void)
forall (f :: * -> *) b a. Monad f => Scope b f a -> f (Var b a)
Bound.fromScope Scope Int Type Void
type_)