[英]Free group monad
在范疇論中, 單子是兩個伴隨函子的組成。 例如,Maybe monad是由健忘的仿函數組成的自由的定點仿函數。 同樣,List monad是由健忘函子組成的免費monoid函子。
Monoid是最簡單的代數結構之一,所以我想知道編程是否可以從更復雜的結構中受益。 我沒有在標准的Haskell軟件包中找到免費的團體monad,所以在這里定義它
data FreeGroup a = Nil | PosCons a (FreeGroup a) | NegCons a (FreeGroup a)
定義==
運算符,使得NegCons x (PosCons xy) == y
。 因此,在length :: FreeGroup a -> Int
,每個PosCons
計數為+1,每個NegCons
-1計數(這是Int的唯一組態,每個PosCons值為+1)。
就像列表(免費monoid)一樣, concat
只是乘法,而map
是函數的函數提升。 所以的單子實例FreeGroup
是完全一樣的List
。
自由團體monad是否有任何編程用途? 同樣,通常在上下文中將monad解釋為值:對於List
,上下文將是選擇或不確定性。 對自由團體莫納德有這樣的解釋嗎?
自由環和向量空間(總是自由的)怎么樣?
對於任何代數結構S
,存在分類自由函子 FS :: Set -> S
的存在意味着函數Haskell調用fold:
foldS :: S s => (a -> s) -> FS a -> s
它在自由對象FS a
上將基於a
的函數提升為S
態。 常用的foldr
函數是foldMonoid
一種特殊化(在Haskell中稱為foldMap
,由於某種原因我不太了解),其類半身像是函數b -> b
的集合,其中組合為乘法。
為了完整起見,這是FreeGroup
的monad實例:
mult :: FreeGroup a -> FreeGroup a -> FreeGroup a
mult Nil x = x
mult x Nil = x
mult (PosCons x y) z = PosCons x (mult y z)
mult (NegCons x y) z = NegCons x (mult y z)
inverse :: FreeGroup a -> FreeGroup a
inverse Nil = Nil
inverse (PosCons x y) = mult (inverse y) (NegCons x Nil)
inverse (NegCons x y) = mult (inverse y) (PosCons x Nil)
groupConcat :: FreeGroup (FreeGroup a) -> FreeGroup a
groupConcat Nil = Nil
groupConcat (PosCons x l) = mult x (groupConcat l)
groupConcat (NegCons x l) = mult (inverse x) (groupConcat l)
instance Functor FreeGroup where
fmap f Nil = Nil
fmap f (PosCons x y) = PosCons (f x) (fmap f y)
fmap f (NegCons x y) = NegCons (f x) (fmap f y)
instance Applicative FreeGroup where
pure x = PosCons x Nil
fs <*> xs = do { f <- fs; x <- xs; return $ f x; }
instance Monad FreeGroup where
l >>= f = groupConcat $ fmap f l
“免費團體monad是否有任何編程用途?”
由於過去四個月缺乏答案,我想答案是“不,不是真的”。 但這是一個有趣的問題,並且由於它基於基本的數學概念,因此在我看來(也是)它應該如此。
首先,我注意到提議的免費小組功能也可以通過以下列表中的一個輕松實現:
type FreeGroupT a = [Either a a]
fgTofgT :: FreeGroup a -> FreeGroupT a
fgTofgT Nil = []
fgTofgT (a :+: as) = Right a : fgToList as
fgTofgT (a :-: as) = Left a : fgToList as
fgTTofg :: FreeGroupT a -> FreeGroup a
fgTTofg [] = Nil
fgTTofg (Right a : as) = a :+: fgTTofg as
fgTTofg (Left a : as) = a :-: fgTTofg as
--using (:-:) instead of NegCons
--and (:+:) instead of PosCons
這是一個很好的定義,因為我們確保我們的自由組只是一個具有一些額外結構的類人。 它指出,自由群只是自由monoid與另一個函子的組合(叫什么名字?不是ab雙函子,而是函子F a = L a | R a)。 我們還確保自由組monad實例與自由monoid的monad實例一致。 也就是說,在自由群上以恰好都是正數的條件運行的單子應該表現得像在自由半身像上的單子一樣,對嗎?
但是最終,如果我們想減少逆,我們需要一個Eq a
實例。 我們將需要在術語級別上工作,純類型級別的信息是不夠的。 據我所知,這使自由monoid和自由組之間的類型級別區分無濟於事。 至少沒有依賴類型。
為了討論實際的編程用途,我將嘗試(但失敗)提供一個合理的用例。
想象一下一個文本編輯器,它使用“ Ctrl”鍵來指示命令序列。 按住“ Ctrl”的同時按下的任何鍵序列在FreeGroup中均被建模為負數(負反面(:-:))。 因此,自由組術語'a':+:'b':+:'b':-:'a':-:[]
可用於建模emacs行為,該行為寫為“ ab”,將光標移回一個字符,然后到該行的開頭。 這樣的設計很好。 我們可以輕松地將命令和宏嵌入流中,而無需保留一些特殊的轉義字符。
然而,這個例子失敗的正確使用的情況下,因為我們希望'a':+:'b':+:'b':-:'a':-:[]
是相同的程序為[]
事實並非如此。 而且,如上所述,它很容易將每個列表項包裝在Either中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.