2017-10-09 109 views
3

使用Bifunctor時,我們可以訪問firstsecond「地圖」功能。所以基本上這是一個Functor,允許我們以兩種不同的方式fmap是否有一個Monoid相當於Bifunctor?

有沒有像Monoid這樣的東西?一些概念允許我們以兩種不同的方式追加?

例如,假設一個不透明的Matrix類型。它不是列表或矢量矢量列表,我們不知道它是如何在內部構造的,但我們知道可以將行和列附加到它。

會有一些類型的類允許這樣做嗎?

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

instance X Matrix where 
    firstAppend = appendRow 
    secondAppend = appendColumn 
+3

我不知道什麼標準的定義。你當然可以自己定義它。我不確定這種價值,因爲在類型層面上沒有任何區別。我認爲一個更合適的解決方案可能是'newtype'包裝器和兩個不同的實例,類似於'Data.Monoid'中的'Product'和'Sum'。 – ryachza

+0

是的@ryachza我認爲這可能是一個更合適的解決方案。 –

+0

這通常以特別的方式完成,例如, [在圖表中](http://hackage.haskell.org/package/diagrams-lib-1.4.1.2/docs/Diagrams-TwoD-Combinators.html#v:-61--61--61-),[matrix ](http://hackage.haskell.org/package/matrix-0.3.5.0/docs/Data-Matrix.html#g:9)或[hmatrix](http://hackage.haskell.org/package/hmatrix -0.18.1.0 /文檔/數字-LinearAlgebra-Data.html#克:12)。 – leftaroundabout

回答

2

我想你可以做這樣的事情與索引幺:​​

{-# 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塊一起)。索引幺半羣的一個小例子:一個在那裏索引並不重要:

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 

我就讓你實現對矩陣的實例;)

+0

真的很喜歡這個解決方案!但實際上我認爲這對我所面臨的問題來說是過度的。非常感謝你 :) –

相關問題