मुझे निम्नलिखित की तरह एक डेटा प्रकार दिया जाता है
data Value = IntVal Integer |
BoolVal Bool
deriving Show
मैं एक फ़ंक्शन getVal
लिखने का प्रयास कर रहा हूं जो एक मान लेता है और वास्तविक मूल्य को अंदर लौटाता है। मैं पैटर्न मिलान के साथ हासिल करने की कोशिश कर रहा था
getVal (IntVal val) = val
getVal (Bool bool) = bool
लेकिन हास्केल ने वापसी के बारे में शिकायत की कि वे वास्तविक प्रकार 'बूल' के साथ अपेक्षित प्रकार 'इंटेगर' से मेल नहीं खा सकते हैं
इसलिए मैंने इसे एक हस्ताक्षर रिटर्न दिया जो एक प्रकार का चर है
getVar :: Value -> a
लेकिन यह भी काम नहीं करेगा
4 जवाब
एक इसे करने का तरीका यह है कि टाइप-क्लास का उपयोग करें, एक फ़ंक्शन बनाने के लिए पॉलीमॉर्फिक रिटर्न वैल्यू में :
\> :t getVal
getVal :: GetValue a => Value -> Maybe a
एक साधारण कोड के रूप में bellow में:
data Value = IntVal Integer
| BoolVal Bool
deriving Show
class GetValue a where
getVal :: Value -> Maybe a
instance GetValue Integer where
getVal (IntVal i) = Just i
getVal _ = Nothing
instance GetValue Bool where
getVal (BoolVal b) = Just b
getVal _ = Nothing
और टाइप-इनफेरेंस सही फंक्शन तय करते हैं:
\> import Data.Maybe (fromJust)
\> (3 +) .fromJust . getVal $ IntVal 5 -- getVal :: Value -> Maybe Integer
8
\> not . fromJust . getVal $ BoolVal False -- getVal :: Value -> Maybe Bool
True
User3237465 और behzad.nouri ने आपके विशिष्ट प्रश्न के उत्तर प्रदान किए हैं। हालाँकि मुझे आश्चर्य है कि अगर आप OO के साथ सादृश्यता और गतिशील रूप से टाइप की गई भाषाओं के बारे में सोच रहे हैं। यदि आप किसी फ़ंक्शन के तर्क के रूप में "मान" ले रहे हैं, तो आपको उस मूल्य के साथ राइट थिंग करने के लिए पैटर्न मिलान का उपयोग करना चाहिए। तो मान लीजिए कि आप एक स्ट्रिंग के रूप में मान लौटाने के लिए एक फ़ंक्शन "showValue" लिख रहे हैं। मुझे लगता है कि आप कुछ करने की कोशिश कर रहे हैं:
showValue :: Value -> String
showValue v = let v1 = getValue v in <something>
लेकिन वह हास्केल में काम नहीं करेगा क्योंकि टाइप सिस्टम यह जानने में जोर देता है कि "v1" क्या है। इसके बजाय आप इसे इस तरह लिखते हैं:
showValue (IntVal i) = "The Value is an integer " ++ show i
showValue (BoolVal b) = "The Value is a boolean " ++ show b
यह GADT
s के लिए एक काम है:
{-# LANGUAGE GADTs #-}
data Value a where
IntVal :: Integer -> Value Integer
BoolVal :: Bool -> Value Bool
getVal :: Value a -> a
getVal (IntVal i) = i
getVal (BoolVal b) = b
हां, इसे प्रकार की कक्षाओं या GADTs की मदद से संभाला जा सकता है या आप cast
लीवरेजिंग Data.Typeable
का भी उपयोग कर सकते हैं। लेकिन जब आप हास्केल को अच्छी तरह से जानते हैं, और जब आप जानते हैं कि आप वास्तव में क्या कर रहे हैं, तो वे सभी चीजें उपयोगी हैं।
आपके मामले में, आपको वास्तव में यह समझने की कोशिश करनी चाहिए कि हास्केल सामान्य रूप से कैसे काम करता है। हास्केल बुद्धिमान हमलावरों को लगाने के बारे में है जो "खराब" कार्यक्रमों को लिखना असंभव बनाते हैं (ठीक है, यह है कि मैं इसे कैसे डालूं)। यह प्रकार प्रणाली के माध्यम से किया जाता है, और उन अपरिवर्तनीयों के बिना आप वास्तव में कुछ भी नहीं कर सकते हैं।
इसलिए अब, आप a
प्रकार की चीज़ के साथ बहुत कुछ नहीं कर सकते, क्योंकि आप इसके बारे में ज्यादा नहीं जानते हैं। यदि आप ऐसे फंक्शन से वैल्यू वापस करना चाहते हैं जो Int
या Bool
हो सकता है (जो कि वास्तव में अस्तित्वगत मात्रा देख सकते हैं), तो आप उस मान पर कार्य कर पाएंगे जो {{X3 पर किया जा सकता है }} और Bool
पर। आप उदाहरण के लिए उस मूल्य का शाब्दिक प्रतिनिधित्व प्राप्त कर सकते हैं।
संभावना है कि आप इससे अधिक चाहते हैं। इस स्थिति में आपको संभवतः Int
और Bool
वापस लौटने की कोशिश नहीं करनी चाहिए, साथ ही साथ यह समझने का कोई तरीका नहीं है कि आपके पास वास्तव में परिणाम क्या है।
तो, आप निम्न उदाहरण के लिए कर सकते हैं:
getVar :: Value -> Either Int Bool
या आप सिर्फ प्रेषण कर सकते हैं:
case Value of
IntVal x -> doWhatYouWantToDoWithInteger x
BoolVal x -> doWhatYouWantToDoWithBoolean x
यह हास्केल का प्राकृतिक प्रवाह है। कार्यक्रम की प्रत्येक शाखा में अब आप जानते हैं कि आप किसके साथ काम कर रहे हैं।
आशा करता हूँ की ये काम करेगा।
संबंधित सवाल
नए सवाल
haskell
हास्केल एक कार्यात्मक प्रोग्रामिंग भाषा है जिसमें मजबूत स्थैतिक टाइपिंग, आलसी मूल्यांकन, व्यापक समानता और संक्षिप्तता समर्थन और अद्वितीय अमूर्त क्षमताओं की विशेषता है।