在关于 Semigroup 的 First Principle book 的 Haskell Programming 练习中,我被要求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
任意性吗?