使用Bifunctor
时,我们可以访问first
和second
“地图”功能。所以基本上它是Functor
,允许我们以两种不同的方式fmap
。
Monoid
是否有这样的内容?一些概念允许我们以两种不同的方式追加?
例如,想象一个不透明的Matrix
类型。它不是列表列表或向量向量,我们不知道它是如何在内部构造的,但我们知道我们可以向其追加行和列。
是否有某些类型允许这样做?
class X a where
firstAppend :: a -> a -> a
secondAppend :: a -> a -> a
instance X Matrix where
firstAppend = appendRow
secondAppend = appendColumn
答案 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
我会让你为矩阵实现实例;)