Universe lifting for type families #
Some functors such as Option
and List
are universe polymorphic. Unlike
type polymorphism where Option α
is a function application and reasoning and
generalizations that apply to functions can be used, Option.{u}
and Option.{v}
are not one function applied to two universe names but one polymorphic definition
instantiated twice. This means that whatever works on Option.{u}
is hard
to transport over to Option.{v}
. ULiftable
is an attempt at improving the situation.
ULiftable Option.{u} Option.{v}
gives us a generic and composable way to use
Option.{u}
in a context that requires Option.{v}
. It is often used in tandem with
ULift
but the two are purposefully decoupled.
Main definitions #
ULiftable
class
Tags #
universe polymorphism functor
Given a universe polymorphic type family M.{u} : Type u₁ → Type u₂
, this class convert between instantiations, from
M.{u} : Type u₁ → Type u₂
to M.{v} : Type v₁ → Type v₂
and back.
f
is an outParam, because g
can almost always be inferred from the current monad.
At any rate, the lift should be unique, as the intent is to only lift the same constants with
different universe parameters.
Instances
Not an instance as it is incompatible with outParam
. In practice it seems not to be needed
anyway.
Equations
- ULiftable.symm f g = { congr := fun {α : Type v₀} {β : Type u₀} (e : α ≃ β) => (ULiftable.congr e.symm).symm }
Instances For
Equations
- ULiftable.refl f = { congr := fun {α β : Type u₀} (e : α ≃ β) => Functor.mapEquiv f e }
The most common practical use ULiftable
(together with down
), the function up.{v}
takes
x : M.{u} α
and lifts it to M.{max u v} (ULift.{v} α)
Equations
- ULiftable.up = (ULiftable.congr Equiv.ulift.symm).toFun
Instances For
The most common practical use of ULiftable
(together with up
), the function down.{v}
takes
x : M.{max u v} (ULift.{v} α)
and lowers it to M.{u} α
Equations
- ULiftable.down = (ULiftable.congr Equiv.ulift.symm).invFun
Instances For
convenient shortcut to avoid manipulating ULift
Equations
- ULiftable.adaptUp F G x f = ULiftable.up x >>= f ∘ ULift.down
Instances For
convenient shortcut to avoid manipulating ULift
Equations
- ULiftable.adaptDown x f = ULiftable.down (x >>= ULiftable.up ∘ f)
Instances For
map function that moves up universes
Equations
- ULiftable.upMap f x = (f ∘ ULift.down) <$> ULiftable.up x
Instances For
map function that moves down universes
Equations
- ULiftable.downMap f x = ULiftable.down ((ULift.up ∘ f) <$> x)
Instances For
Equations
- instULiftableId = { congr := fun {α : Type u_5} {β : Type u_6} (F : α ≃ β) => F }
for specific state types, this function helps to create a uliftable instance
Equations
- StateT.uliftable' F = { congr := fun {α : Type u₀} {β : Type u₁} (G : α ≃ β) => StateT.equiv (F.piCongr fun (x : s) => ULiftable.congr (G.prodCongr F)) }
Instances For
Equations
- instULiftableStateTULift = StateT.uliftable' Equiv.ulift.symm
Equations
- StateT.instULiftableULiftULift = StateT.uliftable' (Equiv.ulift.trans Equiv.ulift.symm)
for specific reader monads, this function helps to create a uliftable instance
Equations
- ReaderT.uliftable' F = { congr := fun {α : Type u₀} {β : Type u₁} (G : α ≃ β) => ReaderT.equiv (F.piCongr fun (x : s) => ULiftable.congr G) }
Instances For
Equations
- instULiftableReaderTULift = ReaderT.uliftable' Equiv.ulift.symm
Equations
- ReaderT.instULiftableULiftULift = ReaderT.uliftable' (Equiv.ulift.trans Equiv.ulift.symm)
for specific continuation passing monads, this function helps to create a uliftable instance
Equations
- ContT.uliftable' F = { congr := fun {α : Type u_1} {β : Type u_2} => ContT.equiv (ULiftable.congr F) }
Instances For
Equations
- instULiftableContTULift = ContT.uliftable' Equiv.ulift.symm
Equations
- ContT.instULiftableULiftULift = ContT.uliftable' (Equiv.ulift.trans Equiv.ulift.symm)
for specific writer monads, this function helps to create a uliftable instance
Equations
- WriterT.uliftable' F = { congr := fun {α : Type u_3} {β : Type u_4} (G : α ≃ β) => WriterT.equiv (ULiftable.congr (G.prodCongr F)) }
Instances For
Equations
- instULiftableWriterTULift = WriterT.uliftable' Equiv.ulift.symm
Equations
- WriterT.instULiftableULiftULift = WriterT.uliftable' (Equiv.ulift.trans Equiv.ulift.symm)
Equations
- Except.instULiftable = { congr := fun {α : Type v₁} {β : Type v₂} (e : α ≃ β) => { toFun := Except.map ⇑e, invFun := Except.map ⇑e.symm, left_inv := ⋯, right_inv := ⋯ } }
Equations
- Option.instULiftable = { congr := fun {α : Type u₀} {β : Type u₁} (e : α ≃ β) => { toFun := Option.map ⇑e, invFun := Option.map ⇑e.symm, left_inv := ⋯, right_inv := ⋯ } }