【问题标题】:Examples of "undoable" applicative functors?“不可撤销”的应用函子的例子?
【发布时间】:2021-11-28 01:28:28
【问题描述】:

我声明了一个关于应用函子的组。从我们通常所说的“动作”来看,这样的组似乎可以使动作撤消

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:选项总是添加不确定性,而不是从中减去。

    • ReadPReadPrec:如上所述。
  • IO:从字面上看,这个实例将是一台时间机器。尽管我们可以取现实与时空的商,但有一个实际的反例:不能忘记一个新的IORef

Undoable 有什么特别有趣的例子吗?

【问题讨论】:

    标签: haskell undo applicative alternative-functor


    【解决方案1】:

    我会考虑这样的事情。不是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,但我不完全确定。

    【讨论】:

    • 类似列表的Applicative 实例是否有效?即,将Map k n 视为ks 的列表,每个都具有多重性n,我们得到一个相当自然的“笛卡尔积,然后将ns 相乘以获得输出多重性”这种事情是一致的现有的列表实例。那么我想AlternativeunionWith (+)
    • 您可以考虑将Map.filter (0/=) . Map.mapKeysWith (+) f 作为您的fmap
    【解决方案2】:

    任何幺半群都可以提升到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,在例如lens 和朋友们。

    【讨论】:

      猜你喜欢
      • 2022-09-29
      • 2011-05-19
      • 2014-07-18
      • 1970-01-01
      • 2021-02-23
      • 2016-10-23
      • 2014-04-01
      • 1970-01-01
      • 2012-11-04
      相关资源
      最近更新 更多