0 | ||| A bridge between a single act of derivation (for a single type) and a user derivation task
15 | --- Particular implementations producing the-core-derivation-function closure ---
20 | , MonadState (ListSet GenSignature, ListSet GenSignature) m -- two queues of gens to be derived, one for known types, one the unknown ones
21 | )
25 | -- I'm using `UN` but containing chars that cannot be present in the code parsed from the Idris frontend.
27 | -- Instead of staticaly ensuring that map holds only correct values, we check dynamically, because it's hard to go through `==`-based lookup of maps.
28 | lookupLengthChecked : (intSig : GenSignature) -> SortedMap GenSignature (ExternalGenSignature, Name) ->
29 | Maybe (Name, Subset ExternalGenSignature $ \extSig => extSig.givenParams.size = intSig.givenParams.size)
35 | deriveAll : NamesInfoInTypes => ConsRecs => (cc : ClosuringContext m) => DeriveBodyForType => DerivationClosure m => Elaboration m =>
38 | (toDeriveKnown, toDeriveUnknown) <- mapHom ((`difference` alreadyDerived) . normalise) <$> get {stateType=(ListSet _, ListSet _)}
40 | (weightFunTys, decls) <- bimap (foldl insert' weightFunTys . join) (decls ++) . unzip <$> for (toList toDeriveKnown) deriveOne
42 | then assert_total $ deriveAll {cc=(alreadyDerived `union` toDeriveKnown, %search)} weightFunTys decls
49 | where
53 | -- 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
55 | (tyWithWeightFuns, genFunBody) <- logBounds Info "deptycheck.derive.type" [sig] $ canonicBody sig name
58 | DeriveBodyForType => ClosuringContext m => Elaboration m => SortedMap GenSignature (ExternalGenSignature, Name) => DerivationClosure m where
62 | -- look for external gens, and call it if exists
65 | logValue Details "deptycheck.derive.closuring.external" [sig] "is used as an external generator" $
66 | (callExternalGen extSig name (var outmostFuelArg) $ rewrite lenEq in values, Just (_ ** extSig.gendOrder))
68 | -- check if internal generator asked for is for a primitive type
70 | fail "Cannot derive generator for the primitive type \{show $ extractTargetTyExpr sig.targetType}, use external instead"
72 | -- remember the task to derive, if necessary
74 | modify $ if isTypeKnown sig.targetType then mapFst $ normalise . List.Set.insert sig else mapSnd $ normalise . List.Set.insert sig
76 | -- call the internal gen
77 | logValue DetailedDebug "deptycheck.derive.closuring.internal" [sig] "is used as an internal generator"
80 | --- Canonic-dischagring function ---
82 | %hide Data.Vect.Dependent.(<*>)
98 | export
100 | SortedMap ExternalGenSignature Name -> (forall m. DerivationClosure m => m a) -> Elab (a, List Decl)
102 | let exts = SortedMap.fromList $ exts.asList <&> \namedSig => (fst $ internalise $ fst namedSig, namedSig)
108 | let derived = sortBy (compare `on` declName . fst) $ derived ++ mapMaybe deriveWeightingFun (Prelude.toList weightingFuns)