В упражнениях по программированию на Haskell из книги Первых принципов по полугруппе меня просят написать quickCheck
для пользовательских классов типов.Классов типов много, но я не понимаю, как написать даже базовые:
Проблемы:
Первый предназначен для Trivial
:
module Exercise where
import Test.QuickCheck
data Trivial =
Trivial
deriving (Eq, Show)
instance Semigroup Trivial where
_ <> _ = undefined
instance Arbitrary Trivial where
arbitrary = return Trivial
semigroupAssoc :: (Eq m, Semigroup m) => m -> m -> m -> Bool
semigroupAssoc a b c = (a <> (b <> c)) == ((a <> b) <> c)
type TrivialAssoc = Trivial -> Trivial -> Trivial -> Bool
второй - для
newtype Identity a = Identity a
, а третий - для:
data Two a b =
Two a b
Мои ответы:
Для первого я изменил выражение instance
на
instance Semigroup Trivial where
_ <> _ = Trivial
и это работает.
Я попробовал следующий код, но второй не работает:
newtype Identity a = Identity a
instance (Semigroup a) => Semigroup (Identity a) where
(Identity a1) <> (Identity a2) = Identity (a1 <> a2)
instance Arbitrary (Identity a) where
arbitrary = return (Identity a)
type IdentityAssoc =
(Identity a0) -> (Identity a1) -> (Identity a2) -> Bool
main :: IO ()
main =
quickCheck (semigroupAssoc :: IdentityAssoc)
Я не понимаю, что должен quickTest
проверьте здесь.Я даже пытался:
import Data.NonEmpty
newtype Identity a = Identity a
instance (Semigroup a) => Semigroup (Identity a) where
(Identity a1) <> (Identity a2) = Identity (a1 <> a2)
instance Arbitrary (Identity a) where
arbitrary = return (Identity a)
type IdentityAssoc =
(Identity (NonEmpty Int)) -> (Identity (NonEmpty Int)) -> (Identity (NonEmpty Int)) -> Bool
main :: IO ()
main =
quickCheck (semigroupAssoc :: IdentityAssoc)
, чтобы сделать параметры параметризованных типов конкретными.Но это тоже не работает.
Для третьего я не знаю, как их написать.Но я думаю, что он похож на второй.
Может кто-нибудь объяснить на них, чтобы я мог понять, как написать instance
параметризованных полугрупп и их quickTest
произвольно?