Skip to content

Commit a7964d6

Browse files
committed
Move singleton-type handling to QueryType.
Also extend isSingletonType to table types and singletonTypeValRec to lambda types ('cause they were different?), and observe that isSingletonType is a pure function.
1 parent b5f2c2c commit a7964d6

File tree

4 files changed

+55
-53
lines changed

4 files changed

+55
-53
lines changed

src/lib/CheckType.hs

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module CheckType (
1111
tryGetType,
1212
checkUnOp, checkBinOp,
1313
isData, asFirstOrderFunction, asFFIFunType,
14-
isSingletonType, singletonTypeVal, asNaryPiType,
14+
asNaryPiType,
1515
) where
1616

1717
import Prelude hiding (id)
@@ -1062,52 +1062,6 @@ checkUnOp op x = do
10621062
where
10631063
u = SomeUIntArg; f = SomeFloatArg; sr = SameReturn
10641064

1065-
-- === singleton types ===
1066-
1067-
-- TODO: the following implementation should be valid:
1068-
-- isSingletonType :: EnvReader m => Type n -> m n Bool
1069-
-- isSingletonType ty =
1070-
-- singletonTypeVal ty >>= \case
1071-
-- Nothing -> return False
1072-
-- Just _ -> return True
1073-
-- But we want to be able to query the singleton-ness of types that we haven't
1074-
-- implemented tangent types for. So instead we do a separate case analysis.
1075-
isSingletonType :: EnvReader m => Type n -> m n Bool
1076-
isSingletonType topTy =
1077-
case checkIsSingleton topTy of
1078-
Just () -> return True
1079-
Nothing -> return False
1080-
where
1081-
checkIsSingleton :: Type n -> Maybe ()
1082-
checkIsSingleton ty = case ty of
1083-
Pi (PiType _ _ body) -> checkIsSingleton body
1084-
StaticRecordTy items -> mapM_ checkIsSingleton items
1085-
TC con -> case con of
1086-
ProdType tys -> mapM_ checkIsSingleton tys
1087-
_ -> Nothing
1088-
_ -> Nothing
1089-
1090-
1091-
singletonTypeVal :: EnvReader m => Type n -> m n (Maybe (Atom n))
1092-
singletonTypeVal ty = liftTyperT do
1093-
singletonTypeVal' ty
1094-
1095-
-- TODO: TypeCon with a single case?
1096-
singletonTypeVal'
1097-
:: (MonadFail2 m, SubstReader Name m, EnvReader2 m, EnvExtender2 m)
1098-
=> Type i -> m i o (Atom o)
1099-
singletonTypeVal' ty = case ty of
1100-
TabPi (TabPiType b body) ->
1101-
substBinders b \b' -> do
1102-
body' <- singletonTypeVal' body
1103-
return $ TabLam $ TabLamExpr b' $ AtomicBlock body'
1104-
StaticRecordTy items -> Record <$> traverse singletonTypeVal' items
1105-
TC con -> case con of
1106-
ProdType tys -> ProdVal <$> traverse singletonTypeVal' tys
1107-
_ -> notASingleton
1108-
_ -> notASingleton
1109-
where notASingleton = fail "not a singleton type"
1110-
11111065
-- === various helpers for querying types ===
11121066

11131067
checkedApplyDataDefParams :: (EnvReader m, Fallible1 m) => DataDef n -> [Type n] -> m n [DataConDef n]

src/lib/Linearize.hs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import GHC.Stack
1616
import Name
1717
import Builder
1818
import Syntax
19-
import CheckType (isSingletonType)
2019
import MTL1
2120
import QueryType
2221
import Util (bindM2)
@@ -144,9 +143,7 @@ liftTangentM args m = liftSubstReaderT $ lift11 $ runReaderT1 args m
144143

145144
isTrivialForAD :: Expr o -> PrimalM i o Bool
146145
isTrivialForAD expr = do
147-
trivialTy <- (maybeTangentType <$> getType expr) >>= \case
148-
Nothing -> return False
149-
Just tTy -> isSingletonType tTy
146+
trivialTy <- any isSingletonType . maybeTangentType <$> getType expr
150147
hasActiveEffs <- getEffects expr >>= \case
151148
Pure -> return False
152149
-- TODO: Be more precise here, such as checking

src/lib/QueryType.hs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ module QueryType (
88
instantiateDataDef, instantiateDepPairTy, instantiatePi, instantiateTabPi,
99
litType, lamExprTy,
1010
numNaryPiArgs, naryLamExprType,
11-
oneEffect, projectLength, sourceNameType, typeAsBinderNest, typeBinOp
11+
oneEffect, projectLength, sourceNameType, typeAsBinderNest, typeBinOp,
12+
isSingletonType, singletonTypeVal,
1213
) where
1314

1415
import Control.Monad
1516
import Data.Foldable (toList)
1617
import Data.List (elemIndex)
1718
import qualified Data.List.NonEmpty as NE
1819
import qualified Data.Map.Strict as M
20+
import Data.Maybe (isJust)
1921
import qualified Data.Set as S
2022

2123
import CheapReduction (cheapNormalize)
@@ -795,3 +797,53 @@ rwsFunEffects rws f = getTypeSubst f >>= \case
795797

796798
deleteEff :: Effect n -> EffectRow n -> EffectRow n
797799
deleteEff eff (EffectRow effs t) = EffectRow (S.delete eff effs) t
800+
801+
-- === singleton types ===
802+
803+
-- The following implementation should be valid:
804+
-- isSingletonType :: EnvReader m => Type n -> m n Bool
805+
-- isSingletonType ty =
806+
-- singletonTypeVal ty >>= \case
807+
-- Nothing -> return False
808+
-- Just _ -> return True
809+
-- But a separate implementation doesn't have to go under binders,
810+
-- because it doesn't have to reconstruct the singleton value (which
811+
-- may be type annotated and whose type may refer to names).
812+
813+
isSingletonType :: Type n -> Bool
814+
isSingletonType topTy = isJust $ checkIsSingleton topTy
815+
where
816+
checkIsSingleton :: Type n -> Maybe ()
817+
checkIsSingleton ty = case ty of
818+
Pi (PiType _ Pure body) -> checkIsSingleton body
819+
TabPi (TabPiType _ body) -> checkIsSingleton body
820+
StaticRecordTy items -> mapM_ checkIsSingleton items
821+
TC con -> case con of
822+
ProdType tys -> mapM_ checkIsSingleton tys
823+
_ -> Nothing
824+
_ -> Nothing
825+
826+
singletonTypeVal :: EnvReader m => Type n -> m n (Maybe (Atom n))
827+
singletonTypeVal ty = liftEnvReaderT $
828+
runSubstReaderT idSubst $ singletonTypeValRec ty
829+
{-# INLINE singletonTypeVal #-}
830+
831+
-- TODO: TypeCon with a single case?
832+
singletonTypeValRec :: Type i
833+
-> SubstReaderT Name (EnvReaderT Maybe) i o (Atom o)
834+
singletonTypeValRec ty = case ty of
835+
Pi (PiType b Pure body) ->
836+
substBinders b \(PiBinder b' ty' arr) -> do
837+
body' <- singletonTypeValRec body
838+
return $ Lam $ LamExpr (LamBinder b' ty' arr Pure) $ AtomicBlock body'
839+
TabPi (TabPiType b body) ->
840+
substBinders b \b' -> do
841+
body' <- singletonTypeValRec body
842+
return $ TabLam $ TabLamExpr b' $ AtomicBlock body'
843+
StaticRecordTy items -> Record <$> traverse singletonTypeValRec items
844+
TC con -> case con of
845+
ProdType tys -> ProdVal <$> traverse singletonTypeValRec tys
846+
_ -> notASingleton
847+
_ -> notASingleton
848+
where notASingleton = fail "not a singleton type"
849+

src/lib/Transpose.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import Control.Monad.Reader
1212
import qualified Data.Set as S
1313

1414
import MTL1
15-
import CheckType (singletonTypeVal)
1615
import Err
1716
import Name
1817
import Syntax

0 commit comments

Comments
 (0)