Skip to content

Instantly share code, notes, and snippets.

@xgrommx
Last active February 26, 2020 22:10
Show Gist options
  • Save xgrommx/b383f907c40a3fb44263f20e977a0555 to your computer and use it in GitHub Desktop.
Save xgrommx/b383f907c40a3fb44263f20e977a0555 to your computer and use it in GitHub Desktop.
X
-- X = presheaf ^ profunctor
-- Yoneda = X (->)
newtype X p f a = X { runX :: forall b. p a b -> f b }
hoistX :: forall p f g. (f ~> g) -> (X p f ~> X p g)
hoistX phi (X f) = X (\g -> phi (f g))
withX :: forall w p f a. (Category p, Functor f, Comonad w, Sieve p w) => (X p f a -> X p f a) -> (f a -> f a)
withX phi = lowerX @p @f . phi . liftX @w @p @f
withX' :: forall w p f g a. (Category p, Functor f, Comonad w, Sieve p w) => (X p f a -> X p g a) -> (f a -> g a)
withX' phi = lowerX @p @g . phi . liftX @w @p @f
arr :: forall a b p. Category p => Profunctor p => (a -> b) -> p a b
arr f = rmap f id
unarr :: forall w p a b. (Comonad w, Sieve p w) => p a b -> a -> b
unarr pab a = extract (sieve pab a)
liftX :: forall w p f. (Comonad w, Sieve p w, Functor f) => f ~> X p f
liftX m = X (\g -> unarr g <$> m)
lowerX :: forall p f. (Category p, Profunctor p) => X p f ~> f
lowerX (X k) = k (arr id)
instance Profunctor p => Functor (X p f) where
fmap f (X m) = X (\k -> m (lmap f k))
transform :: forall f. Functor f => f Int -> f Int
transform = fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) . fmap (*2)
-- Yoneda optimization
{-
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) . fmap (*2) . liftX @(Identity) @(->) @[] $ m =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) . fmap (*2) $ X (\g -> unarr g <$> m) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) . fmap (*2) $ X (\g -> (\x -> runIdentity (Identity $ g x)) <$> m) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) . fmap (*2) $ X (\g -> g <$> m) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) $ X (\k -> (\g -> g <$> m) (lmap (*2) k)) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) $ X (\k -> (lmap (*2) k) <$> m) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) . fmap (+1) $ X (\k -> (k . (*2)) <$> m) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) . fmap (*2) $ X (\k -> (k . (+1) . (*2)) <$> m) =
lowerX @(->) @[] . fmap (+1) . fmap (*2) $ X (\k -> (k . (*2) . (+1) . (*2)) <$> m) =
lowerX @(->) @[] . fmap (+1) $ X (\k -> (k . (*2) . (*2) . (+1) . (*2)) <$> m) =
lowerX @(->) @[] $ X (\k -> (k . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m) =
k (arr id) $ (\k -> (k . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m)
(\k -> (k . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m) (arr id)
((arr id) . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m
((rmap id id) . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m
((id . id) . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m
(id . id . (+1) . (*2) . (*2) . (+1) . (*2)) <$> m
((+1) . (*2) . (*2) . (+1) . (*2)) <$> m
-}
res :: [Int]
res = withX @(Identity) @(->) transform [1,2,3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment