新类型的Haskell Monoid实例问题

时间:2020-07-19 16:22:42

标签: haskell monoids newtype

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

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

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

目标是,如果列表中的所有函数均为true,则foldMap Join函数应返回True,否则,则返回false。

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

2 个答案:

答案 0 :(得分:9)

如果第一个和第二个函数都返回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)

答案 1 :(得分:1)

您的类型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) 实例。这样,您就可以在类型上获取实例,而无需自己实现任何东西,例如:

npm i react-native-network-info



import { NetworkInfo } from "react-native-network-info";
 
// Get Local IP
NetworkInfo.getIPAddress().then(ipAddress => {
  console.log(ipAddress);
});
 
// Get IPv4 IP (priority: WiFi first, cellular second)
NetworkInfo.getIPV4Address().then(ipv4Address => {
  console.log(ipv4Address);
});
 
// Get Broadcast
NetworkInfo.getBroadcast().then(broadcast => {
  console.log(broadcast);
});
 
// Get SSID
NetworkInfo.getSSID().then(ssid => {
  console.log(ssid);
});
 
// Get BSSID
NetworkInfo.getBSSID().then(bssid => {
  console.log(bssid);
});
 
// Get Subnet
NetworkInfo.getSubnet().then(subnet => {
  console.log(subnet);
});
 
// Get Default Gateway IP
NetworkInfo.getGatewayIPAddress().then(defaultGateway => {
  console.log(defaultGateway);
});
 
// Get frequency (supported only for Android)
NetworkInfo.getFrequency().then(frequency => {
  console.log(frequency);
});