简体   繁体   English

Haskell Monoid Instance Question for a newtype

[英]Haskell Monoid Instance Question for a newtype

I am trying to define an instance:我正在尝试定义一个实例:

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

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

The goal is that the function foldMap Join should return True if all functions in the list are true, and false if all are not true.目标是如果列表中的所有函数都为真,则 function foldMap Join 应该返回 True,如果所有函数都不为真,则返回 false。

I understand foldMap, and the instances of Sum and Product for Monoid but am otherwise quite new to writting newtype instances of Monoid.我了解 foldMap,以及 Monoid 的 Sum 和 Product 的实例,但是对于编写 Monoid 的新类型实例来说还是很陌生的。 Any help in the right direction would be appreciated.任何正确方向的帮助将不胜感激。 Thank you.谢谢你。

You can make an new function that returns True if both the first and second function return True , by using (&&) .如果第一个和第二个 function 都返回True ,则可以使用(&&)创建一个新的 function 返回True Then the mempty is a Join function that is True for all input:然后mempty是一个Join function ,对于所有输入都是True

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

Since the introduction of the Semigroup , the (<>) function is an instance of the Semigroup however:由于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)

Your type Join a is isomorphic to a -> All , which already has the Monoid instance that you want.您的类型Join aa -> All同构,它已经具有您想要的Monoid实例。 As such, you can get the instance on your type without having to implement anything yourself, like this:因此,您可以在您的类型上获取实例,而无需自己实现任何东西,如下所示:

{-# 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