【问题标题】:How/can this type be made into a Monoid instance如何/可以将此类型制成 Monoid 实例
【发布时间】:2013-05-29 14:14:53
【问题描述】:

我有数据类型:

data Stuff s = Stuff { name :: s, idx :: Int } 

并希望通过以下实现将其变成一个幺半群:

tmappend :: Stuff s -> Stuff t -> Stuff (s,t) 
tmappend s1 s2 = Stuff (name s1, name s2) (idx s1 + idx s2)

tzero :: Stuff ()
tzero =  Stuff () 0

请注意,可以通过mconcat 获得任意嵌套的元组。

但是 tmappend 当前违反了mappend 的类型签名。这实际上是一个幺半群吗?能不能做成一个更好的类型表示。

【问题讨论】:

    标签: haskell algebraic-data-types monoids


    【解决方案1】:

    这被称为宽松的幺半群函子。我强烈建议您阅读this paper,它显示了 Applicatives 是一种松散的幺半群,您可以将您的类型重新定义为 Applicative 并获得等效的接口:

    instance Applicative Stuff where
        pure a = Stuff a 0
        (Stuff f m) <*> (Stuff x n) = Stuff (f x) (m + n)
    
    tmappend :: (Applicative f) => f a -> f b -> f (a, b)
    tmappend fa fb = (,) <$> fa <*> fb
    
    tzero :: (Applicative f) => f ()
    tzero = pure ()
    

    请注意,tmappend 和 tzero 适用于所有 Applicatives,而不仅仅是 Stuff。我链接的论文更详细地讨论了这个习语。

    【讨论】:

    • 我不知道什么是“松弛幺半群”,我认为您的意思是“松弛幺半群函子”。
    • 是的,我的意思是松散的幺半群函子。我会解决的。
    • 这个Applicative,顺便说一下,可以从Product、Constant、Identity和Sum构建:type Stuff a = Product (Constant (Sum Int)) Identity a。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    相关资源
    最近更新 更多