-
Notifications
You must be signed in to change notification settings - Fork 1
N_P1Ch07b_Functors_AcrossCats
Markdown of literate Haskell program. Program source: /src/CTNotes/P1Ch07b_Functors_AcrossCats.lhs
Ref: https://hackage.haskell.org/package/category-extras-0.53.5/docs/Control-Functor-Categorical.html
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
module CTNotes.P1Ch07b_Functors_AcrossCats where
import Data.Functor.Const (Const(..))
import Control.Category
import Prelude(undefined, ($))
import qualified CTNotes.P1Ch03b_FiniteCats as Finite
category-extras
defines CFunctor
(quoted code):
class (Category r, Category s) => CFunctor f r s | f r -> s, f s -> r where
cmap :: r a b -> s (f a) (f b)
Ignoring functional dependencies I define non-endofunctors as:
class (Category r, Category s) => CFunctor f r s where
cmap :: r a b -> s (f a) (f b)
With PolyKinds
in place this assumes most generic kinds for r
and s
, r :: k1 -> k1 -> *
r :: k2 -> k2 -> *
. That makes the definition usable with non-Hask categories like the categories
I created in N_P1Ch03b_FiniteCats or N_P1Ch03a_NatsCat
Here is one polymorphic instance:
instance (Category r) => CFunctor (Const a) r (->) where
cmap _ (Const v) = Const v
Const
is defined (imported from Data.Functor.Const
base package) as
newtype Const a b = Const { getConst :: a }
λ> :k Const
Const :: * -> k -> *
PolyKinds
keeps kind of b
polymorphic but the destination category has to have objects of kind *
(it does not need to be (->)
).
I was able to define instance of CFunctor
polymorphically (in r
) because Const
does not care about source category.
I am using (->) for destination, because this is what the implementation \Const v -> Const v
uses.
To show that this works, I use category defined in the imported notes N_P1Ch03b_FiniteCats.
test :: Const a (x :: Finite.Object) -> Const a (x :: Finite.Object)
test = cmap Finite.MorphId
But this would not compile:
-- Bad code
test :: Const a (x :: Finite.Object) -> Const a (x :: Finite.Object)
test = cmap Finite.MorphAB
TODO: more examples?