我宣布了一個關于應用函子的小組。從我們通常所說的“動作”來看,這樣的組似乎可以使動作被撤銷:
import Control.Applicative
class Alternative f => Undoable f where
undo :: f a -> f a
作為一個群體,對于所有x :: Undoable f => f a,以下定律應滿足:
x <|> undo x ≡ empty
undo x <|> x ≡ empty
一些實體:
import Control.Arrow
import Data.Functor.Compose
import Data.Functor.Product
import Data.Proxy
instance Undoable Proxy where
undo _ = Proxy
instance (Undoable f, Applicative g) => Undoable (Compose f g) where
undo (Compose x) = Compose (undo x)
instance (Undoable f, Undoable g) => Undoable (Product f g) where
undo (Pair x y) = Pair (undo x) (undo y)
instance Undoable m => Undoable (Kleisli m a) where
undo (Kleisli f) = Kleisli (undo . f)
至少對我來說,這些實體沒有興趣。一些非實體包括:
Maybe: 一旦成功,無論其他選擇如何,它都將永遠成功。[]和ZipList:選項總是添加不確定性,而不是從中減去。ReadP和ReadPrec:正如上面所暗示的。
IO:從字面上看,這個實體將是一臺時光機。盡管我們可以取現實與時空的商,但有一個實際的反例:一個新的IORef不能被遺忘。
有什么特別有趣的例子Undoable嗎?
uj5u.com熱心網友回復:
我會考慮這樣的事情。不是Prelude.Functor因為密鑰需要是可訂購的(也可以是Hashable或僅是Eq,您知道權衡)。
它基本上是一個允許負多重性的多重集。反物質元素。
import qualified Data.Map as Map
import qualified Prelude as Hask
import Data.List (sortOn)
import Control.Category.Constrained.Prelude
import Control.Arrow.Constrained
import Control.Applicative.Constrained
data Dirac n k = Dirac { getOccurences :: Map.Map k n }
instance Real n => Functor (Dirac n) (Ord?(->)) (->) where
fmap (ConstrainedMorphism f) (Dirac m)
= Dirac . Map.fromAscList
. concatMap (\((k,n?):grp) -> case sum $ n? : map snd grp of
0 -> []
μ -> [(k,μ)] )
. groupBy (comparing fst)
. sortOn fst
. map (first f)
$ Map.toList m
和
instance Num n => Undoable (Dirac n) where
undo (Dirac m) = Dirac $ Map.map negate m
我認為可以有一個符合Applicative/Alternative建立在此周圍,但我不完全確定。
uj5u.com熱心網友回復:
任何幺半群都可以提升到一個Alternative:
newtype ViaMonoid m a = ViaMonoid m
instance Monoid m => Applicative (ViaMonoid m) where
pure _ = ViaMonoid mempty
ViaMonoid f <*> ViaMonoid x = ViaMonoid (f <> x)
instance Monoid m => Alternative (ViaMonoid m) where
empty = ViaMonoid mempty
ViaMonoid m <|> ViaMonoid m' = ViaMonoid (m <> m')
任何組都可以提升到Undo:
class Monoid g => Group g where
-- law: g <> inverse g = inverse g <> g = mempty
inverse :: g -> g
instance Group g => Undoable (ViaMonoid g) where
undo (ViaMonoid m) = ViaMonoid (inverse m)
ViaMonoid也被稱為更傳統的名稱Const,在eglens和朋友中使用效果很好。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316833.html
