/ / हास्केल प्रकार मिलान त्रुटि - हैकेल

हास्केल प्रकार मिलान त्रुटि - हैकेल

मैंने निम्न प्रकार के समानार्थी शब्द निम्नानुसार परिभाषित किए हैं:

type Potential = Float
type Label = String
type LabelSet = [String]

इसके अलावा मैंने निम्नलिखित प्रकार को परिभाषित किया है और समानार्थी शब्द टाइप किया है:

data VariableNode = VariableNode Label Potential LabelSet
type PGM = [VariableNode]

अंत में, ग्राफ बनाने के लिए निम्न फ़ंक्शन:

makePGM :: [((Label, Potential), LabelSet)] -> PGM
makePGM (x:xs) = (VariableNode (fst . fst x) (snd . fst x) (snd x)) : makePGM xs
makePGM [] = []

उपरोक्त फ़ंक्शन में, टुपल्स की एक सूची प्रदान की जाती है जहां टुपल का पहला तत्व फ़ंक्शन प्रकार हस्ताक्षर के अनुसार एक और टुपल होता है और दूसरी सूची होती है।

मैं हास्केल के लिए नया हूं इसलिए मुझे निम्न त्रुटि संदेशों को समझने में कुछ कठिनाई है:

Prelude> :l Graph.hs
[1 of 1] Compiling Graph            ( Graph.hs, interpreted )

Graph.hs:14:33: error:
• Couldn"t match type ‘a0 -> c0’ with ‘[Char]’
Expected type: Label
Actual type: a0 -> c0
• Probable cause: ‘(.)’ is applied to too few arguments
In the first argument of ‘VariableNode’, namely ‘(fst . fst x)’
In the first argument of ‘(:)’, namely
‘(VariableNode (fst . fst x) (snd . fst x) (snd x))’
In the expression:
(VariableNode (fst . fst x) (snd . fst x) (snd x)) : makePGM xs

Graph.hs:14:39: error:
• Couldn"t match expected type ‘a0 -> (c0, b0)’
with actual type ‘(Label, Potential)’
• Possible cause: ‘fst’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘fst x’
In the first argument of ‘VariableNode’, namely ‘(fst . fst x)’
In the first argument of ‘(:)’, namely
‘(VariableNode (fst . fst x) (snd . fst x) (snd x))’

Graph.hs:14:47: error:
• Couldn"t match type ‘a1 -> c1’ with ‘Float’
Expected type: Potential
Actual type: a1 -> c1
• Probable cause: ‘(.)’ is applied to too few arguments
In the second argument of ‘VariableNode’, namely ‘(snd . fst x)’
In the first argument of ‘(:)’, namely
‘(VariableNode (fst . fst x) (snd . fst x) (snd x))’
In the expression:
(VariableNode (fst . fst x) (snd . fst x) (snd x)) : makePGM xs

Graph.hs:14:53: error:
• Couldn"t match expected type ‘a1 -> (a2, c1)’
with actual type ‘(Label, Potential)’
• Possible cause: ‘fst’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘fst x’
In the second argument of ‘VariableNode’, namely ‘(snd . fst x)’
In the first argument of ‘(:)’, namely
‘(VariableNode (fst . fst x) (snd . fst x) (snd x))’
Failed, modules loaded: none.

मैंने निष्कर्ष निकाला है कि प्रकार के विसंगतियां हैं लेकिन मुझे यह स्पष्ट नहीं है कि मैंने किस तरह से परिभाषित किया है और कार्य प्रकार हस्ताक्षर हैं।

उत्तर:

जवाब के लिए 2 № 1

समस्या यह है कि f . g x है f . (g x)। इसलिए, प्रकार मेल नहीं खाते:

fst . fst ((1,2),3)
== fst . (fst ((1,2),3))
== fst . (1,2)
== ???? (.) expects a function, not a value

आपको या तो चारों ओर कोष्ठक का उपयोग करना होगा fst . fst या $:

-- reminder:
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)

($) :: (a -> b) -> a -> b
($) f x = f x

(fst . fst) x
== fst (fst  x)

fst $ fst x
== fst (fst x)

आप दोनों को भी जोड़ सकते हैं, उदा। fst . fst $ x, की प्राथमिकता के बाद से $ कम है।


जवाब के लिए 0 № 2

बेशक, यह करने के लिए एक उपयोगी अभ्यास है, औरइस गलती के परिणामस्वरूप आपने ऑपरेटर प्राथमिकता और हास्केल में पार्सिंग को बेहतर ढंग से समझना सीखा है। हालांकि, एक बार जब आपको और अनुभव हो जाए तो आपको पता चलेगा कि आप समस्या से बच सकते हैं, और परिणामस्वरूप सरल कोड के साथ घायल हो सकते हैं कॉल लिखने के बजाय पैटर्न मिलान का उपयोग करना fst तथा snd:

makePGM :: [((Label, Potential), LabelSet)] -> PGM
makePGM (((label, potential), set):xs) = VariableNode label potential set : makePGM xs
makePGM [] = []

अब कोड उस डेटा की तरह आकार दिया गया है, जो आप उपभोग करते हैं, और आप जिन मूल्यों के साथ काम करते हैं उन्हें वर्णनात्मक नाम देना पड़ता है।

एक और सुधार यह देखने से आता हैयह पुनरावर्ती पैटर्न बहुत आम है: आप सूची में प्रत्येक आइटम को एक-दूसरे से स्वतंत्र करते हैं, और परिणामों की एक सूची बनाते हैं। वास्तव में, यह वही है map कर देता है। तो आप एक ऐसा फ़ंक्शन लिख सकते हैं जो एक समय में इनमें से केवल एक पीजीएम आइटम से संबंधित हो, और फिर उपयोग करें map इसे एक ऐसे कार्य में विस्तारित करने के लिए जो उनकी सूची पर काम करता है:

makePGM :: [((Label, Potential), LabelSet)] -> PGM
makePGM = map go
where go ((label, potential), set) = VariableNode label potential set