@@ -398,6 +398,7 @@ monadifyType ctx tp@(asPi -> Just (_, _, tp_out))
398
398
monadifyType ctx tp@ (asPi -> Just (x, tp_in, tp_out)) =
399
399
MTyArrow (monadifyType ctx tp_in)
400
400
(monadifyType ((x,tp,Nothing ): ctx) tp_out)
401
+ monadifyType _ (asTupleType -> Just [] ) = mkMonType0 unitTypeOpenTerm
401
402
monadifyType ctx (asPairType -> Just (tp1, tp2)) =
402
403
MTyPair (monadifyType ctx tp1) (monadifyType ctx tp2)
403
404
monadifyType ctx (asRecordType -> Just tps) =
@@ -529,6 +530,36 @@ fromCompTerm :: MonType -> OpenTerm -> MonTerm
529
530
fromCompTerm mtp t | isBaseType mtp = CompMonTerm mtp t
530
531
fromCompTerm mtp t = ArgMonTerm $ fromArgTerm mtp t
531
532
533
+ -- | Test if a monadification type @tp@ is pure, meaning @MT(tp)=tp@
534
+ monTypeIsPure :: MonType -> Bool
535
+ monTypeIsPure (MTyForall _ _ _) = False -- NOTE: this could potentially be true
536
+ monTypeIsPure (MTyArrow _ _) = False
537
+ monTypeIsPure (MTySeq _ _) = False
538
+ monTypeIsPure (MTyPair mtp1 mtp2) = monTypeIsPure mtp1 && monTypeIsPure mtp2
539
+ monTypeIsPure (MTyRecord fld_mtps) = all (monTypeIsPure . snd ) fld_mtps
540
+ monTypeIsPure (MTyBase _ _) = True
541
+ monTypeIsPure (MTyNum _) = True
542
+
543
+ -- | Test if a monadification type @tp@ is semi-pure, meaning @SemiP(tp) = tp@,
544
+ -- where @SemiP@ is defined in the documentation for 'fromSemiPureTermFun' below
545
+ monTypeIsSemiPure :: MonType -> Bool
546
+ monTypeIsSemiPure (MTyForall _ k tp_f) =
547
+ monTypeIsSemiPure $ tp_f $ MTyBase k $
548
+ -- This dummy OpenTerm should never be inspected by the recursive call
549
+ error " monTypeIsSemiPure"
550
+ monTypeIsSemiPure (MTyArrow tp_in tp_out) =
551
+ monTypeIsPure tp_in && monTypeIsSemiPure tp_out
552
+ monTypeIsSemiPure (MTySeq _ _) = False
553
+ monTypeIsSemiPure (MTyPair mtp1 mtp2) =
554
+ -- NOTE: functions in pairs are not semi-pure; only pure types in pairs are
555
+ -- semi-pure
556
+ monTypeIsPure mtp1 && monTypeIsPure mtp2
557
+ monTypeIsSemiPure (MTyRecord fld_mtps) =
558
+ -- Same as pairs, record types are only semi-pure if they are pure
559
+ all (monTypeIsPure . snd ) fld_mtps
560
+ monTypeIsSemiPure (MTyBase _ _) = True
561
+ monTypeIsSemiPure (MTyNum _) = True
562
+
532
563
-- | Build a monadification term from a function on terms which, when viewed as
533
564
-- a lambda, is a "semi-pure" function of the given monadification type, meaning
534
565
-- it maps terms of argument type @MT(tp)@ to an output value of argument type;
@@ -857,8 +888,13 @@ monadifyTerm' _ (asApplyAll -> (asTypedGlobalDef -> Just glob, args)) =
857
888
do let (macro_args, reg_args) = splitAt (macroNumArgs macro) args
858
889
mtrm_f <- macroApply macro glob macro_args
859
890
monadifyApply mtrm_f reg_args
860
- Nothing -> error (" Monadification failed: unhandled constant: "
861
- ++ globalDefString glob)
891
+ Nothing ->
892
+ monadifyTypeM (globalDefType glob) >>= \ glob_mtp ->
893
+ if monTypeIsSemiPure glob_mtp then
894
+ monadifyApply (ArgMonTerm $ fromSemiPureTerm glob_mtp $
895
+ globalDefOpenTerm glob) args
896
+ else error (" Monadification failed: unhandled constant: "
897
+ ++ globalDefString glob)
862
898
monadifyTerm' _ (asApp -> Just (f, arg)) =
863
899
do mtrm_f <- monadifyTerm Nothing f
864
900
monadifyApply mtrm_f [arg]
@@ -959,6 +995,25 @@ iteMacro = MonMacro 4 $ \_ args ->
959
995
[toCompType mtp, toArgTerm atrm_cond,
960
996
toCompTerm mtrm1, toCompTerm mtrm2]
961
997
998
+ -- | The macro for the either elimination function, which converts the
999
+ -- application @either a b c@ to @either a b (CompM c)@
1000
+ eitherMacro :: MonMacro
1001
+ eitherMacro = MonMacro 3 $ \ _ args ->
1002
+ do let (tp_a, tp_b, tp_c) =
1003
+ case args of
1004
+ [t1, t2, t3] -> (t1, t2, t3)
1005
+ _ -> error " eitherMacro: wrong number of arguments!"
1006
+ mtp_a <- monadifyTypeM tp_a
1007
+ mtp_b <- monadifyTypeM tp_b
1008
+ mtp_c <- monadifyTypeM tp_c
1009
+ let eith_app = applyGlobalOpenTerm " Prelude.either" [toArgType mtp_a,
1010
+ toArgType mtp_b,
1011
+ toCompType mtp_c]
1012
+ let tp_eith = dataTypeOpenTerm " Prelude.Either" [toArgType mtp_a,
1013
+ toArgType mtp_b]
1014
+ return $ fromCompTerm (MTyArrow (MTyArrow mtp_a mtp_c)
1015
+ (MTyArrow (MTyArrow mtp_b mtp_c)
1016
+ (MTyArrow (mkMonType0 tp_eith) mtp_c))) eith_app
962
1017
963
1018
-- | Make a 'MonMacro' that maps a named global whose first argument is @n:Num@
964
1019
-- to a global of semi-pure type that takes an additional argument of type
@@ -1048,6 +1103,7 @@ defaultMonEnv =
1048
1103
mmCustom " Prelude.unsafeAssert" unsafeAssertMacro
1049
1104
, mmCustom " Prelude.ite" iteMacro
1050
1105
, mmCustom " Prelude.fix" fixMacro
1106
+ , mmCustom " Prelude.either" eitherMacro
1051
1107
1052
1108
-- Top-level sequence functions
1053
1109
, mmArg " Cryptol.seqMap" " CryptolM.seqMapM"
0 commit comments