elm-syntax-0.3.0.0: src/Language/Elm/Type.hs
{-# language DeriveFoldable #-}
{-# language DeriveFunctor #-}
{-# language DeriveTraversable #-}
{-# language OverloadedStrings #-}
{-# language TemplateHaskell #-}
module Language.Elm.Type where
import Control.Monad
import Data.Bifunctor
import Data.Eq.Deriving (deriveEq1)
import Data.Foldable
import Data.Ord.Deriving (deriveOrd1)
import Data.String
import Text.Show.Deriving (deriveShow1)
import qualified Language.Elm.Name as Name
data Type v
= Var v
| Global Name.Qualified
| App (Type v) (Type v)
| Fun (Type v) (Type v)
| Record [(Name.Field, Type v)]
deriving (Eq, Ord, Show, Functor, Foldable, Traversable)
deriveEq1 ''Type
deriveOrd1 ''Type
deriveShow1 ''Type
instance Applicative Type where
pure = Var
(<*>) = ap
instance Monad Type where
(>>=) =
flip $ bind Global
bind :: (Name.Qualified -> Type v') -> (v -> Type v') -> Type v -> Type v'
bind global var type_ =
case type_ of
Var v ->
var v
Global g ->
global g
App t1 t2 ->
App (bind global var t1) (bind global var t2)
Fun t1 t2 ->
Fun (bind global var t1) (bind global var t2)
Record fields ->
Record $ second (bind global var) <$> fields
instance IsString (Type v) where
fromString = Global . fromString
apps :: Type v -> [Type v] -> Type v
apps = foldl' App
appsView :: Type v -> (Type v, [Type v])
appsView = go mempty
where
go args typ =
case typ of
App t1 t2 ->
go (t2 : args) t1
_ ->
(typ, args)
funs :: [Type v] -> Type v -> Type v
funs args ret =
foldr Fun ret args
tuple :: Type v -> Type v -> Type v
tuple t1 t2 = apps "Basics.," [t1, t2]
foldMapGlobals
:: Monoid m
=> (Name.Qualified -> m)
-> Type v
-> m
foldMapGlobals f type_ =
case type_ of
Var _ ->
mempty
Global qname ->
f qname
App t1 t2 ->
foldMapGlobals f t1 <> foldMapGlobals f t2
Fun t1 t2 ->
foldMapGlobals f t1 <> foldMapGlobals f t2
Record fields ->
foldMap (foldMap (foldMapGlobals f)) fields