为什么制作幺半群实例不是一个好主意

Har*_*ris 3 haskell

我在 haskell 中设计了以下联合运算符:

data Set a = Set (a-> Bool)

union :: Set a -> Set a -> Set a
union (Set mem1) (Set mem2) = Set ( \x -> mem1 x || mem2 x)

instance Semigroup (Set a) where
  (<>) = union


instance Monoid (Set a) where
  mempty = Set ( \_ -> False)  -- Empty set identity element
  mappend = (<>)               -- Union monoid operation
Run Code Online (Sandbox Code Playgroud)

我知道对于幺半群实例,它需要满足结合律和恒等律。使用联合运算符,它似乎确实满足了这一点。为此创建一个幺半群实例可能会出现什么问题?

Wil*_*sem 6

Monoid实例确实合理且有效。一个可能的问题是,您在这里使用 union 作为Monoid实例,交集是否是相等有效的,因此您选择两者之一。

通常,可以通过将其包装在新类型中来解决此问题,例如:

newtype Union a = Union {unUnion :: Set a}
newtype Intersection a = Intersection {unIntersection :: Set a}

instance Semigroup (Union a) where
    (<>) = union

instance Semigroup (Intersection a) where
    (<>) = intersection

instance Monoid (Union a) where
    mempty = Union (Set (const False))

instance Monoid (Union a) where
    mempty = Intersection (Set (const True))
Run Code Online (Sandbox Code Playgroud)

因此,这里可以将 包裹Set在 aUnion或中Intersection,然后决定使用哪个幺半群。