You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I stumbled across these while implementing Termination Combinators Forever. The termination combinator type Test described therein is the contravariant Coyoneda transformation of the Equivalence functor. Its combinators are characterized by these instances: given Test a ~ Coyoneda Equivalence a, then chosen and divided are exactly the combinators eitherT and pairT, and conquer is alwaysT. These can then be derived automatically, all thanks to -XDerivingVia. (Equivalence technically demands symmetry which WQOs violate, but for deriving instances we can ignore it since we don't derive any others that need it.)
instanceDivisiblef=>Divisible (Coyonedaf) whereconquer::Coyonedafa
conquer =Coyonedaid conquer
{-# INLINE conquer #-}
divide:: (a-> (b, c)) ->Coyonedafb->Coyonedafc->Coyonedafa
divide cleave (Coyoneda fb b) (Coyoneda fc c)
=Coyoneda (bimap fb fc . cleave) (divided b c)
{-# INLINE divide #-}
instanceDecidablef=>Decidable (Coyonedaf) wherelose:: (a->Void) ->Coyonedafa
lose f =Coyonedaid (lose f)
{-# INLINE lose #-}
choose:: (a->Eitherbc) ->Coyonedafb->Coyonedafc->Coyonedafa
choose fork (Coyoneda fb b) (Coyoneda fc c)
=Coyoneda (bimap fb fc . fork) (chosen b c)
{-# INLINE choose #-}
Proof of equality is left as a simple exercise:
-- Generalized implementation of 'Test' from "Termination Combinators Forever"newtypeTest (a::Type) =Test (CoyonedaEquivalencea)
-- DerivingVia is amazing.derivingContravariantvia (CoyonedaEquivalence)
derivingDivisiblevia (CoyonedaEquivalence)
derivingDecidablevia (CoyonedaEquivalence)
-- 'WQO' constructor, backwards-compatible with the-- termination-combinators package/paper.patternWQO::foralla.forallb. (a->b) -> (b->b->Bool) ->TestapatternWQO co eq =Test (Coyoneda co (Equivalence eq))
{-# COMPLETE WQO #-}
Also, while playing around more, I stumbled upon the following instance for contravariant Day:
contract::Divisiblef=>Dayffa->fa
contract (Day ca cb k) = divide k ca cb
instanceDivisiblef=>Divisible (Dayff) whereconquer::Dayffa
conquer = diag conquer
divide:: (a-> (b, c)) ->Dayffb->Dayffc->Dayffa
divide cleave fb fc =Day (contract fb) (contract fc) cleave
I feel there is something lurking within Divisible (Day f f) that can get us to Divisible (Coyoneda f), but I'm not sure.
The text was updated successfully, but these errors were encountered:
I stumbled across these while implementing Termination Combinators Forever. The termination combinator type
Test
described therein is the contravariant Coyoneda transformation of theEquivalence
functor. Its combinators are characterized by these instances: givenTest a ~ Coyoneda Equivalence a
, thenchosen
anddivided
are exactly the combinatorseitherT
andpairT
, andconquer
isalwaysT
. These can then be derived automatically, all thanks to-XDerivingVia
. (Equivalence
technically demands symmetry which WQOs violate, but for deriving instances we can ignore it since we don't derive any others that need it.)Proof of equality is left as a simple exercise:
Also, while playing around more, I stumbled upon the following instance for contravariant
Day
:I feel there is something lurking within
Divisible (Day f f)
that can get us toDivisible (Coyoneda f)
, but I'm not sure.The text was updated successfully, but these errors were encountered: