2012-01-21 19 views
10

है, तो मैं हास्केल में एक साधारण योजना दुभाषिया बनाने की कोशिश कर रहा हूं। इस के हिस्से के रूप में, मैं कुछ आदिम ऑपरेटरों को लागू कर रहा हूं जैसे संख्या ?, स्ट्रिंग? आदिहास्केल फ़ंक्शन जो एक प्रकार और मान लेता है और जांच करता है कि मान

मैं इस तरह कोड है:

isNumber :: [LispVal] -> LispVal 
isNumber ([Number n]) = Bool True 
isNumber   _ = Bool False 

isString :: [LispVal] -> LispVal 
isString ([String n]) = Bool True 
isString   _ = Bool False 

और क्या मैं करना चाहते हैं, जैसे

isType :: ?? -> [LispVal] -> LispVal 
isType (typeName [typeName n]) = Bool True 
isType      _ = Bool False 

दूसरे शब्दों में कुछ है मैं द्वारा ISNUMBER के बराबर बनाना चाहते हैं "आईट टाइप नंबर" कह रहा है। क्या यह किसी भी तरह से संभव है? मैं Google में कुछ भी ढूंढने के लिए संघर्ष कर रहा हूं, शायद क्योंकि मुझे नहीं पता कि स्थिति को क्या कहना है।

+4

आपको शायद "टाइप" के बजाय "कन्स्ट्रक्टर" कहना चाहिए, जैसा कि लिखा है, यह प्रश्न वास्तव में हास्केल के संदर्भ में भी समझ में नहीं आता है। आप हास्केल कन्स्ट्रक्टर के साथ लिस्प प्रकार का प्रतिनिधित्व कर रहे हैं, लेकिन यह सीधे हास्केल प्रश्न के लिए प्रासंगिक नहीं है। – ehird

+0

डेटा। टाइप करने योग्य एक लायक हो सकता है, लेकिन ऐसा नहीं लगता है कि आपको यहां गतिशील जांच की आवश्यकता है। – ExternalReality

+1

[टेम्पलेट हास्केल समाधान] के लिए यहां देखें (http://stackoverflow.com/questions/7213974/how-to-examine-a-quoted-data-constructor-name-in-template-haskell/7214422#7214422)। इसके साथ आप 'isNumber = $ (isA 'संख्या)' – hammar

उत्तर

8

मैं यह सोचते कर रहा हूँ आप इस तरह एक प्रकार कुछ है:

data LispVal = String String | Number Double -- &c.... 

... और आप एक समारोह है कि परीक्षण है कि क्या एक LispVal मूल्य एक विशेष निर्माता है चाहते हैं (String, Number, & सी।) कुछ तर्क के आधार पर।

दुर्भाग्य से ऐसा करने के लिए वास्तव में एक सरल, सामान्य तरीका नहीं है।

आप स्ट्रिंग तुलना का सहारा सकता है:

getTypeName :: LispVal -> String 
getTypeName (String _) = "String" 
getTypeName (Number _) = "Number" 

isType :: String -> [LispVal] -> LispVal 
isType name [val] = Bool (name == getTypeName val) 
isType _ _ = Bool False 

या आप दो LispVal रों के प्रकार की तुलना कर सकते:

sameType :: LispVal -> LispVal -> LispVal 
sameType (String _) (String _) = Bool True 
sameType (Number _) (Number _) = Bool True 
sameType _ _ = Bool False 

... और फिर isType के लिए के साथ तुलना करने के लिए एक डमी मूल्य बनाने ।

तुम भी एक "प्रकार" मूल्य बनाने के लिए और LispVal रों पर प्रतिबिंब का एक तरह लागू कर सकता है, तो उन के आधार पर की तुलना करें:

data LispType = LispString | LispNumber | LispType 

getType :: LispVal -> LispVal 
getType (String _) = Type LispString 
getType (Number _) = Type LispNumber 
getType (Type _) = Type LispType 

isType :: LispVal -> [LispVal] -> LsipVal 
isType t [v] = isEqual t (getType v) 
isType _ _ = Bool False 

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

+0

कर सकते हैं 'सी {}' पैटर्न सिंटैक्स का उपयोग बॉयलरप्लेट को कम करने के लिए' GetType' 'के लिए एक अच्छा विचार हो सकता है। ('GetTypeName' और' sameType' के लिए भी जाता है।) – ehird

+2

'GetType (Type _) = टाइप LispType' ... प्रकार का प्रकार एक प्रकार का प्रकार है? o_O? –

+0

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

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