0 | ||| A bridge between a single act of derivation (for a single type) and a user derivation task
19 | --- Particular implementations producing the-core-derivation-function closure ---
24 | , MonadState (ListSet GenSignature, ListSet GenSignature) m -- two queues of gens to be derived, one for known types, one the unknown ones
25 | )
29 | -- I'm using `UN` but containing chars that cannot be present in the code parsed from the Idris frontend.
31 | -- Instead of staticaly ensuring that map holds only correct values, we check dynamically, because it's hard to go through `==`-based lookup of maps.
32 | lookupLengthChecked : (intSig : GenSignature) -> SortedMap GenSignature (ExternalGenSignature, Name) ->
33 | Maybe (Name, Subset ExternalGenSignature $ \extSig => extSig.givenParams.size = intSig.givenParams.size)
39 | deriveAll : NamesInfoInTypes => ConsRecs => (cc : ClosuringContext m) => DeriveBodyForType => DerivationClosure m => Elaboration m =>
42 | (toDeriveKnown, toDeriveUnknown) <- mapHom ((`difference` alreadyDerived) . normalise) <$> get {stateType=(ListSet _, ListSet _)}
44 | (weightFunTys, decls) <- bimap (foldl insert' weightFunTys . join) (decls ++) . unzip <$> for (toList toDeriveKnown) deriveOne
46 | then assert_total $ deriveAll {cc=(alreadyDerived `union` toDeriveKnown, %search)} weightFunTys decls
53 | where
57 | -- derive declaration and body for the asked signature. It's important to call it AFTER update of the map in the state to not to cycle
59 | (tyWithWeightFuns, genFunBody) <- logBounds Info "deptycheck.derive.type" [sig] $ canonicBody sig name
62 | DeriveBodyForType => ClosuringContext m => Elaboration m => SortedMap GenSignature (ExternalGenSignature, Name) => DerivationClosure m where
66 | -- look for external gens, and call it if exists
69 | logValue Details "deptycheck.derive.closuring.external" [sig] "is used as an external generator" $
70 | (callExternalGen extSig name (var outmostFuelArg) $ rewrite lenEq in values, Just (_ ** extSig.gendOrder))
72 | -- check if internal generator asked for is for a primitive type
74 | fail "Cannot derive generator for the primitive type \{show $ extractTargetTyExpr sig.targetType}, use external instead"
75 | -- the monadic bind is used due to over-normalisation during elaborator script execution causing bad derivator performance otherwise
78 | -- The braces here ↓ are so that the compiler doesn't confuse this with a with application
79 | Nothing : Maybe TTImp <- (if notfound then assert_total specialiseIfNeeded sig fuel values else pure Nothing)
82 | -- remember the task to derive, if necessary
84 | modify $ if isTypeKnown sig.targetType then mapFst $ normalise . List.Set.insert sig else mapSnd $ normalise . List.Set.insert sig
86 | -- call the internal gen
87 | logValue DetailedDebug "deptycheck.derive.closuring.internal" [sig] "is used as an internal generator"
90 | --- Canonic-dischagring function ---
92 | %hide Data.Vect.Dependent.(<*>)
108 | export
110 | SortedMap ExternalGenSignature Name -> (forall m. DerivationClosure m => m a) -> Elab (a, List Decl)
112 | let exts = SortedMap.fromList $ exts.asList <&> \namedSig => (fst $ internalise $ fst namedSig, namedSig)
118 | let derived = sortBy (compare `on` declName . fst) $ derived ++ mapMaybe deriveWeightingFun (Prelude.toList weightingFuns)