Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Monoid equivalent of Bifunctor?

When working with a Bifunctor, we gain access to the first and second "map" functions. So basically it is a Functor that allows us to fmap in two different ways.

Is there something like this for Monoid? Some concept that allows us to append in two different ways?

For example, imagine an opaque Matrix type. It is not a list of lists or a vector of vectors, we have no clue how it is structured inside, but we know that we can append rows and columns to it.

Would there be some type class that allowed to do this?

class X a where
    firstAppend :: a -> a -> a
    secondAppend :: a -> a -> a

instance X Matrix where
    firstAppend = appendRow
    secondAppend = appendColumn
like image 529
Nick Tchayka Avatar asked Nov 17 '25 06:11

Nick Tchayka


1 Answers

I guess you could do something like this with indexed Monoids:

{-# LANGUAGE PolyKinds      #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies   #-}

module IndexedMonoids where

class MonoidIx (m :: k -> *) where
  type Null m :: k
  type Mult m (i :: k) (j :: k) :: k

  nullIx :: m (Null m)
  multIx :: m i -> m j -> m (Mult m i j)

class MonoidIx2 (m :: k -> l -> *) where
  type Null1 m :: k
  type Null2 m :: l
  type Mult1 m (i :: k) (j :: k) :: k
  type Mult2 m (p :: l) (q :: l) :: l

  null1Ix :: m (Null1 m) p
  null2Ix :: m i (Null2 m)
  mult1Ix :: m i p -> m j p -> m (Mult1 m i j) p
  mult2Ix :: m i p -> m i q -> m i (Mult2 m p q)

You'd expect a bunch of laws (identity, associativity, commutativity when you put 4 blocks together). A trivial example of an indexed Monoid: the one where the index does not matter:

newtype Dummy (m :: *) (i :: k) = Dummy { getDummy :: m }

instance Monoid m => MonoidIx (Dummy m :: * -> *) where
  type Null (Dummy m)     = ()
  type Mult (Dummy m) i j = ()

  nullIx = Dummy mempty
  multIx (Dummy i) (Dummy j) = Dummy $ mappend i j

I'll let you implement the instance for matrices ;)

like image 83
gallais Avatar answered Nov 18 '25 19:11

gallais



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!