Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
DerivingVia (Co Any Pair) and (Co All Pair)
{-# Language DeriveFunctor #-}
{-# Language DerivingVia #-}
{-# Language FlexibleContexts #-}
{-# Language FlexibleInstances #-}
{-# Language GADTs #-}
{-# Language GeneralizedNewtypeDeriving #-}
{-# Language InstanceSigs #-}
{-# Language ScopedTypeVariables #-}
{-# Language TypeApplications #-}
{-# Language TypeFamilies #-}
{-# Language ViewPatterns #-}
import Data.Kind
import Data.Coerce
import Data.Semigroup
class Functor f => Representable f where
type Rep f :: Type
index :: f a -> (Rep f -> a)
tabulate :: (Rep f -> a) -> f a
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
duplicate = extend id
extend :: (w a -> b) -> w a -> w b
extend f = fmap f . duplicate
data Pair a = Pair a a
deriving
stock
(Show, Functor)
deriving
(Comonad)
via
(Co All Pair)
instance Representable Pair where
type Rep Pair = Bool
index :: Pair a -> (Bool -> a)
index (Pair a b) False = a
index (Pair a b) True = b
tabulate :: (Bool -> a) -> Pair a
tabulate make = Pair (make False) (make True)
----
newtype Co :: Type -> (Type -> Type) -> (Type -> Type) where
Co :: { unCo :: f a } -> Co rep f a
deriving Functor
instance (Coercible rep (Rep f), Representable f) => Representable (Co rep f) where
type Rep (Co rep f) = rep
tabulate :: (rep -> a) -> Co rep f a
tabulate make = Co $ tabulate $ \(coerce -> rep) -> make rep
index :: Co rep f a -> (rep -> a)
index (Co as) = index as . coerce
instance (Representable f, Coercible rep (Rep f), Monoid rep) => Comonad (Co rep f) where
extract :: Co rep f a -> a
extract (Co as) = as `index` coerce (mempty @rep)
extend :: (Co rep f a -> b) -> (Co rep f a -> Co rep f b)
extend ex (Co as) = Co $ tabulate $ \(coerce -> m) ->
ex $ tabulate (\((m <>) -> (coerce -> m)) -> index as m)
@Icelandjack

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment