Моноид по умолчанию для списков в прелюдии GHC - это конкатенация.
[1,2,3] <> [4,5,6]
становится [1,2,3] ++ [4,5,6]
и, таким образом, [1,2,3,4,5,6]
Я хочу написать экземпляр моноида ZipList, который ведет себя так:
[
1 <> 4
, 2 <> 5
, 3 <> 6
]
Результат - [5,7,9]
, если я использую моноид суммы.
Обратите внимание, что это ведет себя как zipWith (+)
Потенциально он будет вести себя так:
[
Sum 1 <> Sum 4
, Sum 2 <> Sum 5
, Sum 3 <> Sum 6
]
Мне нужно создать новый тип вокруг ZipList
newtype и Sum
newtype, чтобы создать экземпляр для Monoid
, Arbitrary
и EqProp
.
Таким образом избегая сиротских случаев.
Вот как ZipList
и Sum
выглядят в Prelude
:
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
Мне нужна помощь в выяснении, где я ошибся.