2014-09-19 18 views
5

यह घोषणा करने का सबसे अच्छा तरीका क्या है कि घोषणा प्रकार-सही नहीं है? जीएडीटी के साथ, यह समझना मुश्किल नहीं है कि एक कन्स्ट्रक्टर एप्लिकेशन सही है या नहीं। यदि कोई व्यक्ति प्रकार की सुरक्षित संरचनाओं की एक पुस्तकालय लिख रहा है तो यह सुनिश्चित करना स्वाभाविक है कि अवैध निर्माण नहीं बनाया जा सकता है। इसलिए, एक परीक्षण सूट के एक हिस्से के रूप में, मैं यह सुनिश्चित करना चाहता हूं कि कुछ उदाहरण अवैध संरचनाओं को टाइप चेकर द्वारा खारिज कर दिया गया हो।हास्केल: उस कोड का परीक्षण कैसे किया जा रहा है?

उदाहरण के तौर पर, एक आकार-जांच वेक्टर प्रतिनिधित्व देखें। यह उन सामान्य समस्याओं से काफी सरल है जिन्हें मैं तय करना चाहता हूं, लेकिन परीक्षण विधि की जांच करने के लिए यह एक अच्छा उदाहरण है।

data Vector n t where 
    EmptyVec :: Vector 0 t 
    ConsVec :: t -> Vector n t -> Vector (n+1) t 

// TODO: test that it does not typecheck 
illegalVec = ConsVec 'c' (ConsVec "b" EmptyVec) 
+1

आप शायद 'मेटा-टेस्ट' करना चाहते हैं। एक छोटी लिपि लिखें जो आपके कोड को संकलित करने का प्रयास करती है और यह सुनिश्चित करती है कि संकलक कोड 0 से बाहर नहीं निकलता है। – Kris

+1

मुझे लगता है कि आप यहां कुछ प्रकार के आश्रित प्रकारों को लागू करने की कोशिश कर रहे हैं? ... आप यहां किस भाषा एक्सटेंशन का उपयोग करना चाहते हैं? पहले भाग को काम करने के लिए। – Carsten

+1

@ कार्स्टनकॉन्ग: 'टाइपऑपरेटर्स', 'जीएडीटीएस', 'डेटाकिंड्स', और 'जीएचसी। टाइपलेट' का आयात। –

उत्तर

8

आप एचएचसीएल प्रोग्राम से जीएचसीआई को कॉल कर सकते हैं और तारों की जांच के लिए इसका इस्तेमाल कर सकते हैं। hint hackage से इस के लिए एक सुविधाजनक आवरण प्रदान करता है:

{-# LANGUAGE DataKinds, TypeOperators, GADTs #-} 

import GHC.TypeLits 
import Language.Haskell.Interpreter 

data Vector n t where 
    EmptyVec :: Vector 0 t 
    ConsVec :: t -> Vector n t -> Vector (n + 1) t 

main = do 
    print =<< runInterpreter (typeChecks "ConsVec 'c' (ConsVec \"b\" EmptyVec)") 
    -- prints "Right False" 
बेशक

, यह सिर्फ पाठ फ़ाइलों की जाँच के लिए स्क्रिप्ट लिखने के लिए एक और अधिक सुविधाजनक विकल्प है, लेकिन मेरा मानना ​​है कि वहाँ में खुद जाँच प्रकार प्रतिबिंबित करने के लिए एक तरीका नहीं है हास्केल, तो यही वह है जो हमें मिला है।

5

मुझे इसके बजाय जीएचसी के -fdefer-type-errors विकल्प का उपयोग करके (एबी?) के आधार पर एक अलग विचार मिला, जो hint के साथ एक पूर्ण हास्केल दुभाषिया को एम्बेड करने से सस्ता हो सकता है। हालांकि, इसकी आउटपुट थोड़ी गन्दा है, क्योंकि संकलन के दौरान चेतावनियां अभी भी मुद्रित होती हैं, लेकिन अगर आप में फ़ाइल और ghc कमांड पर जीएचसी -w विकल्प के साथ सामान्य रूप से चेतावनियां बंद करने के इच्छुक हैं, तो इसे साफ़ किया जा सकता है। लाइन।

हालांकि मैं इसे एक मॉड्यूल में प्रदर्शित करने के लिए सब कुछ शामिल करता हूं, मुझे लगता है कि इस परीक्षण के विकल्प प्रासंगिक परीक्षण मॉड्यूल में केवल ठीक से सक्षम होना चाहिए।

ध्यान दें कि यह विधि अपने स्थगित प्रकार की त्रुटियों को प्रकट करने के लिए पर्याप्त रूप से पर्याप्त आक्रामक मूल्य का मूल्यांकन करने में सक्षम होने पर निर्भर करती है, जो कुछ उपयोग मामलों में मुश्किल हो सकती है।

{-# OPTIONS_GHC -fdefer-type-errors #-} 
{-# LANGUAGE TypeOperators, GADTs, DataKinds #-} 
{-# LANGUAGE StandaloneDeriving #-} 

import GHC.TypeLits 
import Control.Exception 
import Data.Typeable 

data Vector n t where 
    EmptyVec :: Vector 0 t 
    ConsVec :: t -> Vector n t -> Vector (n+1) t 

-- Add a Show instance so we can evaluate a Vector deeply to catch any 
-- embedded deferred type errors. 
deriving instance Show t => Show (Vector n t) 

illegalVec = ConsVec 'c' (ConsVec "b" EmptyVec) 

test = do 
    t <- try . evaluate $ length (show illegalVec) 
    case t of 
     Right _ -> error "Showing illegalVec gave no error" 
     Left e -> putStrLn $ "\nOk: Showing illegalVec returned error:\n" 
        ++ show (e :: ErrorCall) 
-- ErrorCall is the exception type returned by the error function and seems 
-- also to be used by deferred type errors. 
संबंधित मुद्दे