是否有Monoid等同于Bifunctor?

时间:2017-10-09 12:48:21

标签: haskell typeclass category-theory

使用Bifunctor时,我们可以访问firstsecond“地图”功能。所以基本上它是Functor,允许我们以两种不同的方式fmap

Monoid是否有这样的内容?一些概念允许我们以两种不同的方式追加?

例如,想象一个不透明的Matrix类型。它不是列表列表或向量向量,我们不知道它是如何在内部构造的,但我们知道我们可以向其追加行和列。

是否有某些类型允许这样做?

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

instance X Matrix where
    firstAppend = appendRow
    secondAppend = appendColumn

1 个答案:

答案 0 :(得分:2)

我猜你可以用索引的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)

当你把4个街区放在一起时,你会期待一堆法律(身份,结社,交换性)。索引Monoid的一个简单示例:索引无关紧要的那个:

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

我会让你为矩阵实现实例;)