Created
March 8, 2019 12:19
-
-
Save Icelandjack/eea839698f3dd256ac5f79e05615dc07 to your computer and use it in GitHub Desktop.
DerivingVia (Co Any Pair) and (Co All Pair)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://www.reddit.com/r/haskell/comments/aygshq/extend_and_its_relationship_to_bind/