2017-05-23 33 views
2

我有這種類型的包裝功能如何爲封裝函數的類型編寫任意實例?

newtype Transaction d e r = Transaction (d -> Either e (d,r)) 

...我想爲它的函子&應用型實例做快速檢查測試,但編譯器抱怨說,它不具有任意實例。

我試圖這樣做,但我堅持生成隨機函數。

謝謝!

的快速檢查屬性這樣

type IdProperty f a = f a -> Bool 
functorIdProp :: (Functor f, Eq (f a)) => IdProperty f a 
functorIdProp x = (fmap id x) == id x 

type CompositionProperty f a b c = f a -> Fun a b -> Fun b c -> Bool 
functorCompProp :: (Functor f, Eq (f c)) => CompositionProperty f a b c 
functorCompProp x (apply -> f) (apply -> g) = (fmap (g . f) x) == (fmap g . fmap f $ x) 

instance (Arbitrary ((->) d (Either e (d, a)))) => Arbitrary (DbTr d e a) where 
    arbitrary = do 
     f <- ...??? 
     return $ Transaction f 

...和測試定義== == UPDATE看起來是這樣的:

spec = do 
    describe "Functor properties for (Transaction Int String)" $ do 
    it "IdProperty (Transaction Int String) Int" $ do 
     property (functorIdProp :: IdProperty (Transaction Int String) Int) 

    it "CompositionProperty (Transaction Int String) Int String Float" $ do 
     property (functorCompProp :: CompositionProperty (Transaction Int String) Int String Float) 
+0

[?也許這將是有用的(https://mail.haskell.org/pipermail/haskell- cafe/2010-September/083735.html)但是,我想想你會從這些隨機函數中獲得什麼。我會說,一些邊緣案例是這需要的一切。 –

回答

3

您應該使用Test.QuickCheck.Function包裝器測試功能。如果你只需要爲你的Transaction類型(但如果你真的需要它,你可以找到my answer to this question)測試類型分類法則,那麼ArbitraryCoArbitrary例子對於Transaction似乎沒有意義。

要測試法,你可以在這樣的方式寫屬性:

{-# LANGUAGE DeriveFunctor #-} 

import Test.QuickCheck 
import Test.QuickCheck.Function 

newtype Transaction d e r = Transaction (d -> Either e (d,r)) 
    deriving (Functor) 

-- fmap id ≡ id 
prop_transactionFunctorId :: Int 
          -> Fun Int (Either Bool (Int,String)) 
          -> Bool 
prop_transactionFunctorId d (Fun _ f) = let t    = Transaction f 
              Transaction f' = fmap id t 
             in f' d == f d 

那麼,這可能看起來不漂亮,漂亮,只要你想。但是這是測試任意函數的好方法。例如,我們可以最後一行in f' d == f d更換到in f' d == f 1,看看它是如何失敗的,如果它失敗:

ghci> quickCheck prop_transactionFunctorId 
*** Failed! Falsifiable (after 2 tests and 4 shrinks):  
0 
{0->Left False, _->Right (0,"")} 
+0

我看到這個,但我想以通用的方式定義Functor屬性。看到我上面的代碼。這樣我就不必重寫我寫的每種類型的屬性 – vidi

+0

StateT問題的鏈接很好。謝謝! – vidi

相關問題