free-foil-0.3.2: Efficient Type-Safe Capture-Avoiding Substitution for Free (Scoped Monads)
Safe HaskellNone
LanguageHaskell2010

Data.ZipMatchK

Description

Kind-polymorphic syntactic (first-order) unification.

Synopsis

Documentation

class ZipMatchK (f :: k) where Source #

Kind-polymorphic syntactic (first-order) unification of two values.

Note: f is expected to be a traversable n-functor, but at the moment we lack a TraversableK constraint.

The default implementation is generic, via RepK. It is convenient, but it reflects each node into a representation and back on every comparison, and a constructor is represented as a chain of L1/R1 wrappers as long as its index, so the cost grows with the size of the signature. On a 44-constructor signature it costs about 1.8 times the time and 2.3 times the allocation of the written-out instance, and comparing terms is most of what a typechecker does. Use deriveZipMatchK (or deriveZipMatchK2, for a signature bifunctor with extra parameters) to generate the written-out instance instead.

Minimal complete definition

Nothing

Methods

zipMatchWithK :: forall (as :: LoT k) (bs :: LoT k) (cs :: LoT k). Mappings as bs cs -> (f :@@: as) -> (f :@@: bs) -> Maybe (f :@@: cs) Source #

Perform one level of equality testing:

  • when k = Type, values are compared directly (e.g. via Eq);
  • when k = Type -> Type, we compare term constructors; if term constructors are unequal, we return Nothing; otherwise, we pair up all components with a given function.

default zipMatchWithK :: forall (as :: LoT k) (bs :: LoT k) (cs :: LoT k). (GenericK f, GZipMatch (RepK f), ReqsZipMatchWith (RepK f) as bs cs) => Mappings as bs cs -> (f :@@: as) -> (f :@@: bs) -> Maybe (f :@@: cs) Source #

Instances

Instances details
ZipMatchK Either Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type -> Type)) (bs :: LoT (Type -> Type -> Type)) (cs :: LoT (Type -> Type -> Type)). Mappings as bs cs -> (Either :@@: as) -> (Either :@@: bs) -> Maybe (Either :@@: cs) Source #

ZipMatchK (,) Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type -> Type)) (bs :: LoT (Type -> Type -> Type)) (cs :: LoT (Type -> Type -> Type)). Mappings as bs cs -> ((,) :@@: as) -> ((,) :@@: bs) -> Maybe ((,) :@@: cs) Source #

ZipMatchK NonEmpty Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> (NonEmpty :@@: as) -> (NonEmpty :@@: bs) -> Maybe (NonEmpty :@@: cs) Source #

ZipMatchK Maybe Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> (Maybe :@@: as) -> (Maybe :@@: bs) -> Maybe (Maybe :@@: cs) Source #

ZipMatchK [] Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> ([] :@@: as) -> ([] :@@: bs) -> Maybe ([] :@@: cs) Source #

ZipMatchK a => ZipMatchK (Either a :: Type -> Type) Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> (Either a :@@: as) -> (Either a :@@: bs) -> Maybe (Either a :@@: cs) Source #

ZipMatchK a => ZipMatchK ((,) a :: Type -> Type) Source # 
Instance details

Defined in Data.ZipMatchK.Generic

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> ((,) a :@@: as) -> ((,) a :@@: bs) -> Maybe ((,) a :@@: cs) Source #

(ZipMatchK ann, ZipMatchK sig) => ZipMatchK (AnnSig ann sig :: Type -> Type -> Type) Source #

Matching for AnnSig is derived, not left to the generic default.

The generic default would rebuild the Generics.Kind view of every node on every comparison, and comparing terms is most of what a typechecker does, so for an annotated signature — where it lands on the hottest path — that is a measurable cost. deriveZipMatchK2 generates the written-out instance instead: the annotation matched with the term zipper (an annotation is a functor of the term), the inner signature with both. Write deriveZipMatchK2 ''YourAnnSig for a bespoke annotated signature.

Instance details

Defined in Control.Monad.Free.Foil.Annotated

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type -> Type)) (bs :: LoT (Type -> Type -> Type)) (cs :: LoT (Type -> Type -> Type)). Mappings as bs cs -> (AnnSig ann sig :@@: as) -> (AnnSig ann sig :@@: bs) -> Maybe (AnnSig ann sig :@@: cs) Source #

(Traversable f, Traversable g, ZipMatchK f, ZipMatchK g) => ZipMatchK (Product f g :: Type -> Type) Source #

Note: instance is limited to Type-kinded bifunctors f and g.

Instance details

Defined in Data.ZipMatchK.Functor

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> (Product f g :@@: as) -> (Product f g :@@: bs) -> Maybe (Product f g :@@: cs) Source #

(Traversable f, Traversable g, ZipMatchK f, ZipMatchK g) => ZipMatchK (Sum f g :: Type -> Type) Source #

Note: instance is limited to Type-kinded bifunctors f and g.

Instance details

Defined in Data.ZipMatchK.Functor

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type)) (bs :: LoT (Type -> Type)) (cs :: LoT (Type -> Type)). Mappings as bs cs -> (Sum f g :@@: as) -> (Sum f g :@@: bs) -> Maybe (Sum f g :@@: cs) Source #

(Bitraversable f, Bitraversable g, ZipMatchK f, ZipMatchK g) => ZipMatchK (Product f g :: Type -> Type -> Type) Source #

Note: instance is limited to Type-kinded bifunctors f and g.

Instance details

Defined in Data.ZipMatchK.Bifunctor

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type -> Type)) (bs :: LoT (Type -> Type -> Type)) (cs :: LoT (Type -> Type -> Type)). Mappings as bs cs -> (Product f g :@@: as) -> (Product f g :@@: bs) -> Maybe (Product f g :@@: cs) Source #

(Bitraversable f, Bitraversable g, ZipMatchK f, ZipMatchK g) => ZipMatchK (Sum f g :: Type -> Type -> Type) Source #

Note: instance is limited to Type-kinded bifunctors f and g.

Instance details

Defined in Data.ZipMatchK.Bifunctor

Methods

zipMatchWithK :: forall (as :: LoT (Type -> Type -> Type)) (bs :: LoT (Type -> Type -> Type)) (cs :: LoT (Type -> Type -> Type)). Mappings as bs cs -> (Sum f g :@@: as) -> (Sum f g :@@: bs) -> Maybe (Sum f g :@@: cs) Source #

zipMatchK :: forall {k} (f :: k) (as :: LoT k) (bs :: LoT k). (ZipMatchK f, PairMappings as bs) => (f :@@: as) -> (f :@@: bs) -> Maybe (f :@@: ZipLoT as bs) Source #

Perform one level of equality testing for two values and pair up components using (,):

zipMatchK = zipMatchWithK (\x y -> Just (,) :^: M0)

Specializations

Unification of plain Types

zipMatchViaEq :: forall {k} a (as :: LoT k) (bs :: LoT k) (cs :: LoT k). Eq a => Mappings as bs cs -> a -> a -> Maybe a Source #

Unify values via Eq. Can be used as an implementation of zipMatchWithK when k = Type.

zipMatchViaChooseLeft :: forall {k} (as :: LoT k) (bs :: LoT k) (cs :: LoT k) a. Mappings as bs cs -> a -> a -> Maybe a Source #

Always successfully unify any two values of type a by preferring the left value. Can be used as an implementation of zipMatchWithK when k = Type.

Unification of Functors

zipMatchWith1 :: (Traversable f, ZipMatchK f) => (a -> a' -> Maybe a'') -> f a -> f a' -> Maybe (f a'') Source #

zipMatchWithK specialised to functors.

Note: Traversable is a morally correct constraint here.

zipMatch1 :: (Traversable f, ZipMatchK f) => f a -> f a' -> Maybe (f (a, a')) Source #

zipMatchK specialised to functors.

Note: Traversable is a morally correct constraint here.

Unification of Bifunctors

zipMatchWith2 :: (Bitraversable f, ZipMatchK f) => (a -> a' -> Maybe a'') -> (b -> b' -> Maybe b'') -> f a b -> f a' b' -> Maybe (f a'' b'') Source #

zipMatchWithK specialised to bifunctors.

Note: Bitraversable is a morally correct constraint here.

zipMatch2 :: (Bitraversable f, ZipMatchK f) => f a b -> f a' b' -> Maybe (f (a, a') (b, b')) Source #

zipMatchK specialised to bifunctors.

Note: Bitraversable is a morally correct constraint here.