packages feed

apple-0.3.0.0: src/Ty/M.hs

{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE OverloadedStrings #-}

module Ty.M ( check, RE (..) ) where

import           A
import           Control.Applicative (Alternative (..))
import           Control.DeepSeq     (NFData)
import           Data.Foldable       (asum)
import           GHC.Generics        (Generic)
import           Prettyprinter       (Pretty (..), squotes, (<+>))

data RE = MR (E (T ())) (T ()) | Unflat (E (T ())) (T ()) | UT (E (T ())) (T ()) | IS (Sh ()) | ES (Sh ()) deriving (Generic)

instance NFData RE where

instance Pretty RE where
    pretty (MR e t)     = "Type" <+> squotes (pretty t) <+> "of expression" <+> squotes (pretty e) <+> "is not sufficiently monomorphic."
    pretty (Unflat e t) = "Error in expression" <+> squotes (pretty e) <+> "of type" <+> squotes (pretty t) <> ": arrays of functions are not supported."
    pretty (UT e t)     = "Type" <+> squotes (pretty t) <+> "of expression" <+> squotes (pretty e) <+> "tuples of arrays of tuples are not supported"
    pretty (IS s)       = "𝔯 requires statically known dimensions; inferred shape" <+> squotes (pretty s)
    pretty (ES s)       = "👁️ requires statically known dimensions; inferred shape" <+> squotes (pretty s)

check = cM

cM :: E (T ()) -> Maybe RE
cM e | Just t <- mrT (eAnn e) = Just (MR e t)
cM e | Just t <- flT (eAnn e) = Just (Unflat e t)
cM e | Just t <- ata (eAnn e) = Just (UT e t)
cM (Builtin (Arrow _ (Arrow _ (Arr sh _))) R) | dynSh sh = Just (IS sh)
cM (Builtin (Arr sh _) Eye) | dynSh sh = Just (ES sh)
cM (Let _ (_, e) e') = cM e <|> cM e'
cM (LLet _ (_, e) e') = cM e <|> cM e'
cM (Def _ _ e') = cM e' -- FIXME hm
cM (EApp _ e e') = cM e <|> cM e'
cM (ALit _ es) = foldMapAlternative cM es
cM (Lam _ _ e) = cM e
cM (Cond _ p e e') = cM p <|> cM e <|> cM e'
cM (Tup _ es) = foldMapAlternative cM es
cM Builtin{} = Nothing
cM ILit{} = Nothing
cM FLit{} = Nothing
cM BLit{} = Nothing
cM Var{} = Nothing

mrT :: T a -> Maybe (T a)
mrT t@TVar{}     = Just t
mrT (Arr _ t)    = mrT t
mrT (Arrow t t') = mrT t <|> mrT t'
mrT (P ts)       = foldMapAlternative mrT ts
mrT t@Ρ{}        = Just t
mrT _            = Nothing

flT :: T a -> Maybe (T a)
flT t@(Arr _ tϵ) | ha tϵ = Just t
flT (Arrow t t') = flT t <|> flT t'
flT (P ts) = foldMapAlternative flT ts
flT _ = Nothing

ha :: T a -> Bool
ha Arrow{}   = True
ha (P ts)    = any ha ts
ha (Arr _ t) = ha t
ha _         = False

har :: T a -> Bool
har Arr{} = True; har (P ts) = any har ts; har _ = False

ata :: T a -> Maybe (T a)
ata t@(Arr _ (P ts)) | any har ts = Just t
ata (Arrow t t') = ata t <|> ata t'
ata (P t) = foldMapAlternative ata t
ata _ = Nothing

dynI :: I a -> Bool
dynI Ix{}      = False
dynI IVar{}    = True
dynI IEVar{}   = True
dynI StaPlus{} = True
dynI StaMul{}  = True

dynSh :: Sh a -> Bool
dynSh SVar{}      = True
dynSh Nil         = False
dynSh (Cons i sh) = dynI i || dynSh sh
dynSh Rev{}       = True
dynSh Cat{}       = True
dynSh Π{}         = True

foldMapAlternative :: (Traversable t, Alternative f) => (a -> f b) -> t a -> f b
foldMapAlternative f xs = asum (f <$> xs)