我宣布了一个关于应用函子的小组。从我们通常所说的“动作”来看,似乎这样的组可以使动作被撤消:
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
:一旦成功,无论其他选择如何,它总是会成功。[]
andZipList
: 选项总是添加不确定性,而不是从中减去。ReadP
和ReadPrec
:如上所述。
IO
: 从字面上看,这个实例将是一台时间机器。即使我们可以取现实与时空的商,也有一个实际的反例:一个新的IORef
不能被遗忘。
有什么特别有趣的例子Undoable
吗?