HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulelinear-base-0.4.0Haskell2010

Control.Functor.Linear.Internal.Kan

A few things lifted from kan-extensions and lens for generic deriving of Traversable instances (see Data.Functor.Linear.Internal.Traversable).

  • 2 types
  • 4 values
newtypenewtype Curried (g :: Type -> Type) (h :: Type -> Type) a
#

A linear version of Data.Functor.Day.Curried.Curried in the kan-extensions package. We use this for generic traversals. How does it help? Consider a type like

data Foo a = Foo a a a a

The generic representation may look roughly like

D1 _ (C1 _ ((S1 _ Rec1 :*: S1 _ Rec1) :*: (S1 _ Rec1 :*: S1 _ Rec1)))

Traversing this naively requires a bunch of fmap applications. Most of them could be removed using Yoneda, but one aspect can't be. Let's simplify down to the hard bit:

m :*: (n :*: o)

Traversing this looks like

((:*:) $ m) * ((:*:) $ n * o)

We want to reassociate the applications so the whole reconstruction of the generic representation happens in one place, allowing inlining to (hopefully) erase them altogether. It will end up looking roughly like

(x y z -> x :*: (y :*: z)) $ m * n * o

In our context, we always have the two functor arguments the same, so something like Curried f f. Curried f f a is a lot like f a, as demonstrated directly by lowerCurriedC and, in kan-extensions, liftCurried. It's a sort of "continuation passing style" version. If we have something like

Con $ m * n * o

-- parenthesized

((Con $ m) * n) * o

we can look at what happens next to each field. So the next thing after performing m is to map Con over it. The next thing after performing n is to apply Con $ m to it within the functor.

Constructors

  • Curried
    • runCurried :: forall r. g (a %1 -> r) %1 -> h r
Instances4Functor, Applicative
  • (Functor g, g ~ h) => Applicative (Curried g h)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
  • Functor g => Functor (Curried g h)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
  • Functor g => Functor (Curried g h)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
  • (Functor g, g ~ h) => Applicative (Curried g h)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
valuelowerCurriedC :: Applicative f => Curried f g a %1 -> g a
#
newtypenewtype Yoneda (f :: Type -> Type) a
#

Constructors

  • Yoneda
    • runYoneda :: forall b. (a %1 -> b) %1 -> f b
Instances4Functor, Applicative
  • Applicative f => Applicative (Yoneda f)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
  • Functor (Yoneda f)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
  • Functor (Yoneda f)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
  • Applicative f => Applicative (Yoneda f)Defined in linear-base-0.4.0 · Control.Functor.Linear.Internal.Kan
valuelowerYoneda :: Yoneda f a %1 -> f a
#
valueliftCurriedYonedaC
  1. :: Applicative f
  2. => f a
  3. -> Curried (Yoneda f) (Yoneda f) a
#
valueyap :: Applicative f => Yoneda f (a %1 -> b) %1 -> f a %1 -> Yoneda f b
#