首页 > 解决方案 > 新类型的 Haskell Monoid 实例问题

问题描述

我正在尝试定义一个实例:

newtype Join a = Join { getJoin :: a -> Bool }
   deriving Generic

instance Monoid (Join a) where
   f <> g = ???
   mempty = ???

目标是如果列表中的所有函数都为真,则函数 foldMap Join 应该返回 True,如果所有函数都不为真,则返回 false。

我了解 foldMap,以及 Monoid 的 Sum 和 Product 的实例,但是对于编写 Monoid 的新类型实例来说还是很陌生的。任何正确方向的帮助将不胜感激。谢谢你。

标签: haskellmonoidsnewtypederivingderivingvia

解决方案


True如果第一个和第二个函数都返回,您可以True使用(&&). 然后mempty是一个适用于所有输入的Join函数:True

instance Monoid (Join a) where
    Join f <> Join g = Join (\x -> f x && g x)
    mempty = Join (const True)

自从引入 后Semigroup,该(<>)函数就是Semigroup然而的一个实例:

import Control.Applicative(liftA2)

instance Semigroup (Join a) where
    Join f <> Join g = Join (liftA2 (&&) f g)

instance Monoid (Join a) where
    mappend = (<>)
    mconcat js = Join (\x -> all (($ x) . getJoin) js)
    mempty = Join (const True)

推荐阅读