Search code examples
haskellinstancecategory-theory

in Haskell, how do I derive: instance Category (Moore a b -> Moore b c)


I am trying to derive a Category instance for Moore automaton transformers, where:

data Moore a b = Moore b (a -> Moore a b)
type MooreT a b c = (Moore a b -> Moore a c)

The problem is, that MooreT has 3 parameters, whereas Category has only 2. I tried writing: instance Category (MooreT a), but I didn't work.

The thing is, that the parameter a really doesn't matter for the definition of id and (.). E.g:

id :: MooreT a b b
id x = x

Is there a way to define such an instance? Or do I have to define MooreT for a specific type a, like type IntMooreT a b = MooreT Int a b?

I am still new to Haskell, so I'm sorry, if this is a dumb question.


Solution

  • MooreT a is a type synonym for a subtype of (->). (->) already has a Category instance, so MooreT a does too.

    ghci can check to see if MooreTs already compose with .. Start with your definitions and the imports for Category, checking that we have the right . imported

    Prelude> data Moore a b = Moore b (a -> Moore a b)
    Prelude> type MooreT a b c = (Moore a b -> Moore a c)
    Prelude> :t (.)
    (.) :: (b -> c) -> (a -> b) -> a -> c
    Prelude> import Control.Category
    Prelude Control.Category> import Prelude hiding ((.), id)
    Control.Category Prelude> :t (.)
    (.) :: Category cat => cat b c -> cat a b -> cat a c
    

    Make a couple dummy MooreT values, f and g

    Control.Category Prelude> data A = A
    Control.Category Prelude> data B = B
    Control.Category Prelude> data C = C
    Control.Category Prelude> data D = D
    Control.Category Prelude> f = undefined :: MooreT A B C
    Control.Category Prelude> :t f
    f :: MooreT A B C
    Control.Category Prelude> g = undefined :: MooreT A C D
    

    Check that composition works

    Control.Category Prelude> :t g . f
    g . f :: Moore A B -> Moore A D