मुझे निम्नलिखित की तरह एक डेटा प्रकार दिया जाता है

data Value = IntVal Integer |
             BoolVal Bool
             deriving Show

मैं एक फ़ंक्शन getVal लिखने का प्रयास कर रहा हूं जो एक मान लेता है और वास्तविक मूल्य को अंदर लौटाता है। मैं पैटर्न मिलान के साथ हासिल करने की कोशिश कर रहा था

getVal (IntVal val) = val
getVal (Bool bool) = bool

लेकिन हास्केल ने वापसी के बारे में शिकायत की कि वे वास्तविक प्रकार 'बूल' के साथ अपेक्षित प्रकार 'इंटेगर' से मेल नहीं खा सकते हैं

इसलिए मैंने इसे एक हस्ताक्षर रिटर्न दिया जो एक प्रकार का चर है

getVar :: Value -> a

लेकिन यह भी काम नहीं करेगा

3
Frank Tian 29 नवम्बर 2015, 17:29

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
4
behzad.nouri 29 नवम्बर 2015, 14:54

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
2
Paul Johnson 29 नवम्बर 2015, 15:21

यह 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
3
user3237465 29 नवम्बर 2015, 15:02

हां, इसे प्रकार की कक्षाओं या 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

यह हास्केल का प्राकृतिक प्रवाह है। कार्यक्रम की प्रत्येक शाखा में अब आप जानते हैं कि आप किसके साथ काम कर रहे हैं।

आशा करता हूँ की ये काम करेगा।

10
Mark Karpov 29 नवम्बर 2015, 16:14