繁体   English   中英

Haskell Monoid Instance Question for a newtype

[英]Haskell Monoid Instance Question for a newtype

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

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

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

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

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

如果第一个和第二个 function 都返回True ,则可以使用(&&)创建一个新的 function 返回True 然后mempty是一个Join function ,对于所有输入都是True

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

由于Semigroup的引入, (<>) function 是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)

您的类型Join aa -> All同构,它已经具有您想要的Monoid实例。 因此,您可以在您的类型上获取实例,而无需自己实现任何东西,如下所示:

{-# LANGUAGE DerivingVia #-}

import Data.Monoid

newtype Join a = Join { getJoin :: a -> Bool }
   deriving Generic -- not needed for the Monoid instance; I only left it here to show you how to do two different kinds of deriving on the same type, since you derived this already in your question
   deriving (Semigroup, Monoid) via (a -> All)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM