簡體   English   中英

如何在參數化類型上編寫“ Semigroup”實例及其“ quickCheck”對象?

[英]How to write `Semigroup` instance and their `quickCheck`s on parameterized types?

在Semigroup的《第一原理》一書中的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)

使參數化類型的參數具體化。 但這也不起作用。

第三,我不知道該怎么寫。 但我認為它類似於第二個。

有人可以對此進行解釋,以便我了解如何編寫參數化quickTest instance及其quickTest任意對象嗎?

這是錯誤的:

instance Arbitrary (Identity a) where
  arbitrary = return (Identity a)

a不是值變量,而是類型變量。 我們需要類型的值, a傳遞給Identity構造函數,而不是a類型本身。

所以我們需要像

instance Arbitrary a => Arbitrary (Identity a) where
  arbitrary = do
     x <- arbitrary         -- generate a value of type a
     return (Identity x)    -- turn it into a value of type (Identity a)

(或更簡潔地說, arbitrary = Identity <$> arbitrary

請注意,我們必須如何要求a是我們可以為其生成隨機樣本的類型(在Instance之后添加Arbitrary a => )。 否則,我們不能使用x <- arbitrarya生成樣本。

進一步:

type IdentityAssoc =
  (Identity a0) -> (Identity a1) -> (Identity a2) -> Bool

這里我們不能引用a1,a1,a2 ,因為我們還沒有在任何地方定義這些類型。 我們需要選擇具體類型,例如Int 此外,這三種類型必須是同一類型,因為(<>)接受兩個相同類型的值,並返回該類型的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM