module Language.PureScript.AST.Utils where

import Protolude

import Language.PureScript.AST
import Language.PureScript.Names
import Language.PureScript.Types

lam :: Ident -> Expr -> Expr
lam :: Ident -> Expr -> Expr
lam = Binder -> Expr -> Expr
Abs forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> Binder
mkBinder

lamCase :: Ident -> [CaseAlternative] -> Expr
lamCase :: Ident -> [CaseAlternative] -> Expr
lamCase Ident
s = Ident -> Expr -> Expr
lam Ident
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr] -> [CaseAlternative] -> Expr
Case [Ident -> Expr
mkVar Ident
s]

lamCase2 :: Ident -> Ident -> [CaseAlternative] -> Expr
lamCase2 :: Ident -> Ident -> [CaseAlternative] -> Expr
lamCase2 Ident
s Ident
t = Ident -> Expr -> Expr
lam Ident
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> Expr -> Expr
lam Ident
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr] -> [CaseAlternative] -> Expr
Case [Ident -> Expr
mkVar Ident
s, Ident -> Expr
mkVar Ident
t]

mkRef :: Qualified Ident -> Expr
mkRef :: Qualified Ident -> Expr
mkRef = SourceSpan -> Qualified Ident -> Expr
Var SourceSpan
nullSourceSpan

mkVarMn :: Maybe ModuleName -> Ident -> Expr
mkVarMn :: Maybe ModuleName -> Ident -> Expr
mkVarMn Maybe ModuleName
mn = Qualified Ident -> Expr
mkRef forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. QualifiedBy -> a -> Qualified a
Qualified (Maybe ModuleName -> QualifiedBy
byMaybeModuleName Maybe ModuleName
mn)

mkVar :: Ident -> Expr
mkVar :: Ident -> Expr
mkVar = Maybe ModuleName -> Ident -> Expr
mkVarMn forall a. Maybe a
Nothing

mkBinder :: Ident -> Binder
mkBinder :: Ident -> Binder
mkBinder = SourceSpan -> Ident -> Binder
VarBinder SourceSpan
nullSourceSpan

mkLit :: Literal Expr -> Expr
mkLit :: Literal Expr -> Expr
mkLit = SourceSpan -> Literal Expr -> Expr
Literal SourceSpan
nullSourceSpan

mkCtor :: ModuleName -> ProperName 'ConstructorName -> Expr
mkCtor :: ModuleName -> ProperName 'ConstructorName -> Expr
mkCtor ModuleName
mn ProperName 'ConstructorName
name = SourceSpan -> Qualified (ProperName 'ConstructorName) -> Expr
Constructor SourceSpan
nullSourceSpan (forall a. QualifiedBy -> a -> Qualified a
Qualified (ModuleName -> QualifiedBy
ByModuleName ModuleName
mn) ProperName 'ConstructorName
name)

mkCtorBinder :: ModuleName -> ProperName 'ConstructorName -> [Binder] -> Binder
mkCtorBinder :: ModuleName -> ProperName 'ConstructorName -> [Binder] -> Binder
mkCtorBinder ModuleName
mn ProperName 'ConstructorName
name = SourceSpan
-> Qualified (ProperName 'ConstructorName) -> [Binder] -> Binder
ConstructorBinder SourceSpan
nullSourceSpan (forall a. QualifiedBy -> a -> Qualified a
Qualified (ModuleName -> QualifiedBy
ByModuleName ModuleName
mn) ProperName 'ConstructorName
name)

unguarded :: Expr -> [GuardedExpr]
unguarded :: Expr -> [GuardedExpr]
unguarded Expr
e = [Expr -> GuardedExpr
MkUnguarded Expr
e]

unwrapTypeConstructor :: SourceType -> Maybe (Qualified (ProperName 'TypeName), [SourceType], [SourceType])
unwrapTypeConstructor :: SourceType
-> Maybe
     (Qualified (ProperName 'TypeName), [SourceType], [SourceType])
unwrapTypeConstructor = forall {a}.
[Type a]
-> [Type a]
-> Type a
-> Maybe (Qualified (ProperName 'TypeName), [Type a], [Type a])
go [] []
  where
  go :: [Type a]
-> [Type a]
-> Type a
-> Maybe (Qualified (ProperName 'TypeName), [Type a], [Type a])
go [Type a]
kargs [Type a]
args = \case
    TypeConstructor a
_ Qualified (ProperName 'TypeName)
tyCon -> forall a. a -> Maybe a
Just (Qualified (ProperName 'TypeName)
tyCon, [Type a]
kargs, [Type a]
args)
    TypeApp a
_ Type a
ty Type a
arg -> [Type a]
-> [Type a]
-> Type a
-> Maybe (Qualified (ProperName 'TypeName), [Type a], [Type a])
go [Type a]
kargs (Type a
arg forall a. a -> [a] -> [a]
: [Type a]
args) Type a
ty
    KindApp a
_ Type a
ty Type a
karg -> [Type a]
-> [Type a]
-> Type a
-> Maybe (Qualified (ProperName 'TypeName), [Type a], [Type a])
go (Type a
karg forall a. a -> [a] -> [a]
: [Type a]
kargs) [Type a]
args Type a
ty
    Type a
_ -> forall a. Maybe a
Nothing