2015-07-29 3 views
18

Testing Monadic Code with QuickCheck (Claessen, Hughes 2002) में, assert प्रकार का है:Test.QuickCheck.Monadic: क्यों ज़ोर बूल लिए आवेदन किया है, नहीं Testable एक => एक

:

assert :: (Monad m, Testable a) => a -> PropertyM m() 

हालांकि, Test.QuickCheck.Monadic में, यह प्रकार है

assert :: (Monad m) => Bool -> PropertyM m() 

assert लाइब्रेरी में बाद का प्रकार क्यों है?

+1

शायद स्रोत में टिप्पणियां कुछ मदद की होंगी: [(लिंक)] (https://github.com/nick8325/quickcheck/blob/master/Test/QuickCheck/Monadic.hs#L118-126)। दिलचस्प है कि 'assert' के लिए टिप्पणी में पेपर की सिग है, और' स्टॉप 'मूल रूप से एक ही सिग है। – ErikR

उत्तर

4

मुझे लगता है कि यह तकनीकी बाधाओं के कारण था, क्योंकि वर्तमान में Test.QuickCheck पुस्तकालय के साथ एक Testable मूल्यांकन करने के लिए, आप quickCheck* काम करता है, जो बहुत IO केंद्रित कर रहे हैं में से एक का उपयोग करने की आवश्यकता है। ऐसा इसलिए होता है क्योंकि क्विक चेक Testable गुणों को यादृच्छिक रूप से संभावित इनपुट (डिफ़ॉल्ट रूप से 100) उत्पन्न करके परीक्षण करता है, counterexample खोजने की कोशिश करता है जो संपत्ति को झूठा साबित करता है। यदि ऐसा इनपुट नहीं मिला है, तो संपत्ति को सत्य माना जाता है (हालांकि यह जरूरी नहीं है कि सत्य है; वहां एक काउंटररेक्स नमूना हो सकता है जिसका परीक्षण नहीं किया गया था)। और हास्केल में यादृच्छिक इनपुट उत्पन्न करने में सक्षम होने के लिए, हम IO मोनड पर फंस गए हैं।

ध्यान दें कि assert को इस तरह के सामान्य तरीके से परिभाषित किया गया था, यह केवल Bool के साथ सभी पेपर के माध्यम से उपयोग किया जाता है। इसलिए लाइब्रेरी लेखक (पेपर के समान) ने इस बिंदु पर किसी भी मोनैड को मजबूर करने के लिए सामान्य Bool के लिए जेनेरिक Testable पैरामीटर बलिदान करना पसंद किया।

और हम देख सकते हैं कि वे भी source code में एक टिप्पणी के रूप में मूल हस्ताक्षर लिखा है:

-- assert :: Testable prop => prop -> PropertyM m() 

भी ध्यान रखें कि इस तथ्य stop समारोह एक ऐसी ही हस्ताक्षर है के बावजूद:

stop :: (Testable prop, Monad m) => prop -> PropertyM m a 

यह पेपर में assert फ़ंक्शन के समान नहीं है, क्योंकि पूर्व रोकें बी में गणना ओथ मामले या तो स्थिति True या False है। दूसरी ओर, assert केवल अभिकलन बंद हो जाएगा अगर हालत False है:

⟦जोर सच »पी⟧ = ⟦पी⟧

⟦जोर झूठी» पी⟧ = {झूठी वापसी}

import Control.Monad 
import Control.Monad.Trans 
import Test.QuickCheck 
import Test.QuickCheck.Monadic 
import Test.QuickCheck.Property 
import Test.QuickCheck.Test 

assertIO :: Testable prop => prop -> PropertyM IO() 
assertIO p = do r <- liftIO $ quickCheckWithResult stdArgs{chatty = False} p 
       unless (isSuccess r) $ fail "Assertion failed" 
:

हालांकि हम आसानी से कागज से assert समारोह की एक IO संस्करण लिख सकें

और अब हम assertIO और stop के बीच मतभेदों को देखने के लिए एक परीक्षण कर सकते हैं:

prop_assert :: Property 
prop_assert = monadicIO $ do assertIO succeeded 
          assertIO failed 

prop_stop :: Property 
prop_stop = monadicIO $ do stop succeeded 
          stop failed 

main :: IO() 
main = do putStrLn "prop_assert:" 
      quickCheck prop_assert 
      putStrLn "prop_stop:" 
      quickCheck prop_stop 

succeeded और failedTrue और False क्रमश द्वारा प्रतिस्थापित किया जा सकता है। यह दिखाने के लिए कि अब हम Bool तक सीमित नहीं हैं, इसके बजाय हम किसी भी Testable का उपयोग कर सकते हैं।

और उत्पादन होता है:

prop_assert:
*** विफल! दावा विफल रहा (1 परीक्षण के बाद):
prop_stop:
+++ ठीक है, 100 परीक्षण पास हुए।

हम देख सकते हैं, तथ्य यह है कि पहले assertIO सफल होने के बावजूद prop_assert दूसरा assertIO के कारण विफल। दूसरी ओर, prop_stop ने परीक्षा उत्तीर्ण की, क्योंकि पहले stop सफल हुए और उस बिंदु पर गणना बंद हो गई, दूसरे stop का परीक्षण नहीं किया।

+0

लेकिन कारण यह है कि 'क्विक चेक *' फ़ंक्शंस बहुत आईओ-केंद्रित हैं ", यदि यह लाइब्रेरी में प्रस्तावित लाइब्रेरी में सामान्यता को छोड़ देता है। – frasertweedale

+0

@frasertweedale समस्या यह है कि क्विक चेक परीक्षण [टेस्टेबल 'गुणों को यादृच्छिक रूप से संभावित इनपुट (डिफ़ॉल्ट रूप से 100) उत्पन्न करके, [counterexample] (https://en.wikipedia.org/wiki/Counterexample) ढूंढने का प्रयास कर रहा है जो संपत्ति साबित करता है असत्य। यदि ऐसा इनपुट नहीं मिला है, तो संपत्ति सत्य मानी जाती है (हालांकि यह जरूरी नहीं है कि सत्य है; वहां एक काउंटररेक्स नमूना हो सकता है जिसे परीक्षण नहीं किया गया था)। और हास्केल में यादृच्छिक इनपुट उत्पन्न करने में सक्षम होने के लिए, हम 'आईओ' मोनैड पर फंस गए हैं। ध्यान दें कि अगर इस तरह के सामान्य तरीके से 'जोर' को परिभाषित किया गया था, तो इसका उपयोग केवल 'बूल' के साथ ही सभी कागज़ों के माध्यम से किया जाता है। –

+0

ठीक है, थोड़ा स्पष्ट हो रहा है .. उपरोक्त बिंदु आपके उत्तर में शामिल होना अच्छा होगा। – frasertweedale

संबंधित मुद्दे