packages feed

alms-0.6.0: src/Type/Analyses.hs

module Type.Analyses (
  inferKinds,
  isMonoType,
  tyPatToType,
  tyPatKinds,
) where

import Util
import Type.Internal
import Type.TyVar

import Prelude ()
import qualified Data.Set as S

-- | Find the kinds of the rib 0 type variables in an opened type, where
--   the given 'Int' is the width of the rib.
inferKinds ∷ Ord tv ⇒ Type tv → [Kind]
inferKinds = varianceToKind <$$> loop 0 where
  loop k (TyQu _ _ σ)             = loop (k + 1) σ
  loop k (TyVar (Bound i j _))
    | i == k                      = replicate j 0 ++ 1 : repeat 0
    | otherwise                   = repeat 0
  loop _ (TyVar (Free _))         = repeat 0
  loop k (TyApp tc σs)            =
    foldr (zipWith (+)) (repeat 0)
      [ let σ' = if isQVariance var
                   then qualToType σ
                   else σ
         in (* var) <$> loop k σ'
      | var ← tcArity tc
      | σ   ← σs ]
  loop k (TyRow _ σ1 σ2)          = zipWith (+) (loop k σ1) (loop k σ2)
  loop k (TyMu _ σ)               = loop (k + 1) σ

-- | Is the given type monomorphic (quantifer free)?
isMonoType ∷ Ord tv ⇒ Type tv → Bool
isMonoType = foldType (\_ ns k → k (() <$ ns) (\_ → False))
                      (\_ _ _ → False)
                      (\_ → True)
                      (\_ → and)
                      (\_ → (&&))
                      (\_ k → k () id)

-- | Convert a type pattern to a type.
tyPatToType ∷ TyPat → Type Int
tyPatToType tp0 = evalState (loop tp0) [0..]
  where
  loop (TpVar _)      = fvTy <$> next
  loop (TpRow _)      = tyBinOp tcRowMap (tyNulOp tcRowHole) . fvTy <$> next
  loop (TpApp tc tps) = TyApp tc <$> mapM loop tps
  next = do
    i:rest ← get
    put rest
    return i

-- | Find out the variances, qualifier-involvement, guardedness and
--   'QLit' bounds of the type variables in a type pattern.
tyPatKinds ∷ TyPat → [(Variance, Bool, Bool, QLit)]
tyPatKinds = loop 1 True False Qa where
  loop !variance !involved !guarded !bound tp0 = case tp0 of
    TpVar _      → [(variance, involved, guarded, bound)]
    TpRow _      → [(variance, involved, guarded, bound)]
    TpApp tc tps →
      concat
        [ loop (vi * variance)
               (involved && S.member i ftv_qe)
               (guarded || gi)
               (if bound == Qu && involved
                  then Qu
                  else bi)
               tpi
        | i        ← [ 0 .. ]
        | vi       ← tcArity tc
        | gi       ← tcGuards tc
        | bi       ← tcBounds tc
        | tpi      ← tps ]
      where ftv_qe = ftvSet (tcQual tc)