Haskell中的布尔幺半群

6

当然,数据类型并不是精确的,但这大致上是如何实现Monoid Bool的?

import Data.Monoid

data Bool' = T | F deriving (Show)

instance Monoid (Bool') where
    mempty = T
    mappend T _ = T
    mappend _ T = T
    mappend _ _ = F 

如果是/不是,为什么要将Boolmappend设置为OR而不是AND

2个回答

19

对于 Bool,有两种可能的 Monoid 实例,因此 Data.Monoid 使用新类型来区分我们打算使用哪个实例:

-- | Boolean monoid under conjunction.
newtype All = All { getAll :: Bool }
        deriving (Eq, Ord, Read, Show, Bounded, Generic)

instance Monoid All where
        mempty = All True
        All x `mappend` All y = All (x && y)

-- | Boolean monoid under disjunction.
newtype Any = Any { getAny :: Bool }
        deriving (Eq, Ord, Read, Show, Bounded, Generic)

instance Monoid Any where
        mempty = Any False
        Any x `mappend` Any y = Any (x || y)

编辑:正如Ørjan所指出的,实际上有四个有效实例。


1
谢谢。我不确定这是否完全是一个单独的问题,但为什么要使用newtype而不是data呢?谢谢。 - Kevin Meredith
14
实际上有四个。(&&),(||), (==), (/=) 都可以成为幺半群运算。但是最后两个没有预定义。 - Ørjan Johansen
2
@AndrewC 在我看来,True 对于 (==) 实例是 mempty,而 False 对于 (/=) 实例也是 mempty。此外,在这种情况下,如果其中一个 mempty 定律得到满足,另一个也会被满足,因为 (==)(/=) 都是可交换的。 - David Young
1
@2016rshah 这被称为“记录语法”,你可以在这里了解更多信息:链接,标题为“记录语法”的部分。 - Gabriella Gonzalez
3
其中八个不符合条件,因为它们的<>具有T <> F /= F <> T,这意味着既不是F也不是Tmempty。另外两个不符合条件,因为它们的<>具有T <> F = F = T <> T,这意味着既不是F也不是Tmempty。另外两个不符合条件,因为它们的<>T <> F = T = F <> F,这意味着既不是F也不是Tmempty。其余的四个是&&||==/= - rampion
显示剩余9条评论

5

您提供的实例不是一个单子。

mappend F mempty
mappend F T  -- by definition of mempty
T            -- by definition of mappend

我们已经证明了 F <> mempty === T,但对于任何交换半群,x <> mempty === x

Any 的单位是 False,而 All 的单位是 True


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接