繁体   English   中英

ZipList Monoid haskell

[英]ZipList Monoid haskell

GHC Prelude 中列表的默认幺半群是串联。

[1,2,3] <> [4,5,6]变成[1,2,3] ++ [4,5,6][1,2,3,4,5,6]

我想编写一个行为如下的 ZipList Monoid 实例:

[
  1 <> 4
, 2 <> 5
, 3 <> 6
]

结果是[5,7,9]假设我使用的是和幺半群。 请注意,这类似于zipWith (+)

可能它的行为是这样的:

[
  Sum 1 <> Sum 4
, Sum 2 <> Sum 5
, Sum 3 <> Sum 6
]

我需要围绕ZipListSum创建一个新类型,以便为MonoidArbitraryEqProp创建一个实例。 从而避免孤儿实例。 这是ZipListSumPrelude样子:

newtype ZipList a = ZipList { getZipList :: [a] }
newtype Sum a = Sum { getSum :: a }

这就是我的MyZipList样子:它看起来对吗?

newtype MyZipList a =
  MyZipList (ZipList [a])
  deriving (Eq, Show)

instance Monoid a => Monoid (MyZipList a) where
  mempty = MyZipList (ZipList [])

  mappend (MyZipList z) (MyZipList z') =
    MyZipList $ liftA2 mappend z z'

instance Arbitrary a => Arbitrary (MyZipList a) where
  arbitrary = MyZipList <$> arbitrary

instance Eq a => EqProp (MyZipList a) where
  (=-=) = eq

这就是我的MySum样子:这看起来对吗?

newtype MySum a =
  MySum (Sum a)
  deriving (Eq, Show)

 instance (Num a, Monoid a) => Monoid (MySum a) where
   mempty = MySum mempty

   mappend (MySum s) (MySum s') = MySum $ s <> s'

 instance Arbitrary a => Arbitrary (MySum a) where
   arbitrary = MySum <$> arbitrary

我需要帮助找出我哪里出错了。

首先请注意ZipListApplicative实例已经具有您想要的 zippy 行为。

ghci> liftA2 (<>) (Sum <$> ZipList [1,2,3]) (Sum <$> ZipList [4,5,6]) :: ZipList Int
ZipList [Sum 5, Sum 7, Sum 9]

然后利用这样一个事实,即任何Applicative通过幺半群函子本身提升其内容的幺半群行为,从而产生一个Monoid半群。 计划是从我上面写的表达式中抽象出liftA2 (<>)模式。

newtype Ap f a = Ap { getAp :: f a }
instance (Applicative f, Monoid a) => Monoid (Ap f a) where
    mempty = Ap $ pure mempty
    Ap xs `mappend` Ap ys = Ap $ liftA2 mappend xs ys

(据我所知, base缺少这个newtype ,这对我来说似乎是一个疏忽,尽管可能有一个很好的理由。事实上,我认为ZipList应该有一个开箱即用的Monoid实例,但是,唉,它没有。)

你想要的Monoid就是Ap ZipList (Sum Int) 这相当于你手工编写的MyZipList Monoid (除了你的mempty的错误 - 它应该是MyZipList $ ZipList $ repeat mempty ),但是用像这样的可重用newtype s 组成它不是特别的,需要更少的样板.

暂无
暂无

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

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