簡體   English   中英

QuickCheck測試依賴類型

[英]QuickCheck tests for dependent types

我正在編寫依賴類型的VectorMatrix數據類型。

data Vector n e where
  EmptyVector :: Vector Zero e
  (:>)        :: e -> Vector n e -> Vector (Succ n) e

deriving instance Eq e => Eq (Vector n e)

infixr :>

data Matrix r c e where
  EmptyMatrix :: Matrix Zero c e
  (:/)        :: Vector c e -> Matrix r c e -> Matrix (Succ r) c e

deriving instance Eq e => Eq (Matrix r c e)

infixr :/

它們取決於自然數,也取決於類型。

data Natural where
    Zero :: Natural
    Succ :: Natural -> Natural

我編寫了一個函數來計算矩陣中的列數。

columns :: Matrix r c e -> Int
columns m = Fold.foldr (\_ n -> 1 + n) 0 $ getRow 0 m

getRow :: Int -> Matrix r c e -> Vector c e
getRow 0 (v :/ _)    = v
getRow i (_ :/ m)    = getRow (i - 1) m
getRow _ EmptyMatrix = error "Cannot getRow from EmptyMatrix."

我現在想使用QuickCheck測試columns函數。

為此,我必須將MatrixVector聲明為QuickCheck提供的Arbitrary類型類的實例。

但是,我不知道如何做到這一點。

  • 我的數據是否依賴於類型的事實會影響我編寫這些實例的方式嗎?

  • 如何生成任意長度的矩陣,確保它們與定義匹配(例如(Succ(Succ r))將有兩行)?

您可以編寫在編譯時已知的特定長度的實例:

instance Arbitrary (Vector Zero e) where
    arbitrary = return EmptyVector

instance (Arbitrary e, Arbitrary (Vector n e))
    => Arbitrary (Vector (Succ n) e) where
    arbitrary = do
      e <- arbitrary
      es <- arbitrary
      return (e :> es)

除非你想為你想要嘗試的每個長度寫一個表達式(或者讓template-haskell生成那些表達式),否則上面的實例本身並不是很有用。 Int決定類型n應該是什么的一種方法是在存在主義中隱藏n

data BoxM e where
    BoxM :: Arbitrary (Vector c e) => Matrix r c e -> BoxM e

data Box e where Box :: Arbitrary (Vector c e) => Vector c e -> Box e

addRow :: Gen e -> BoxM e -> Gen (BoxM e)
addRow mkE (BoxM es) = do
    e <- mkE
    return $ BoxM (e :/ es)

firstRow :: Arbitrary a => [a] -> BoxM a
firstRow es = case foldr (\e (Box es) -> Box (e :> es)) (Box EmptyVector) es of
    Box v -> BoxM (v :/ EmptyMatrix)

使用addRow和firstRow,編寫mkBoxM :: Int -> Int -> Gen (BoxM Int)應該非常簡單,然后使用它:

forAll (choose (0,3)) $ \n -> forAll (choose (0,3)) $ \m -> do
      BoxM matrix <- mkBoxM n m
      return $ columns matrix == m -- or whatever actually makes sense

暫無
暫無

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

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