2009-04-03 19 views
6

Cabbage.hs:इस प्रकार परिवर्तनीय अस्पष्ट क्यों है?

Cabbage.hs:7:19: 
    Ambiguous type variable `a' in the constraint: 
     `Cabbage a' arising from a use of `foo' at Cabbage.hs:7:19-38 
    Probable fix: add a type signature that fixes these type variable(s) 

मुझे समझ नहीं आता क्यों a अस्पष्ट है:

module Cabbage where 
class Cabbage a 
    where foo :: a -> String  -- the parameter is only present for its type, 
           -- the parameter value will be ignored 
     bar :: String -> a 
quux :: Cabbage a => String -> a 
quux s = bar (s ++ foo (undefined :: a)) 

जब मैं (GHC) के साथ संकलन मैं यह त्रुटि संदेश मिलता है। निश्चित रूप से लाइन 7 में a लाइन 6 में a जैसा ही है? मैं यह कैसे तय करुं?

वैकल्पिक रूप से, प्रति-आवृत्ति निरंतर घोषित करने का एक बेहतर तरीका है?

उत्तर

11

scoped प्रकार चर का उपयोग करके आप दे सकते हैं GHC जानते हैं कि undefined :: a एक ही होना चाहिए (अन्यथा a सिर्फ forall a. a के लिए एक आशुलिपि है)। स्कोप प्रकार चर तो स्पष्ट रूप से forall योग्य होना चाहिए:

{-# LANGUAGE ScopedTypeVariables #-} 
module Cabbage where 
class Cabbage a 
    where foo :: a -> String  -- the parameter is only present for its type, 
           -- the parameter value will be ignored 
     bar :: String -> a 
quux :: forall a. Cabbage a => String -> a 
quux s = bar (s ++ foo (undefined :: a)) 
2

समस्या यह है कि हास्केल को पता नहीं है कि Cabbage का कौन सा उदाहरण foo वहां से मेल खाता है। अब तक मुझे पता है, यह a में quux :: Cabbage a => String -> a

यह मानते हुए कि तुम क्या चाहते हो के साथ (undefined :: a) में a से मेल नहीं खाता है, तो आप ऐसा कर सकते हैं:

quux :: Cabbage a => String -> a 
quux s = result 
    where result = bar (s ++ foo result) 

इस foo बांध और इसलिए है कि एक साथ बार यह दोनों के लिए एक ही उदाहरण का उपयोग करता है, और चूंकि आपको वास्तव में foo के इनपुट के मूल्य की आवश्यकता नहीं है, इसलिए यह बाहर निकलता है। हालांकि मुझे प्रति-उदाहरण स्थिरांक करने का बेहतर तरीका पता नहीं है। उम्मीद है कि कोई और कौन करेगा जो करता है।

2

आप एक समारोह

quux :: Cabbage a => String -> a 
quux s = quux' undefined 
    where quux' :: Cabbage a => a -> a 
      quux' x = bar (s ++ foo x) 
के रूप में बहुरूपी हिस्सा बाहर निकाल सकते हैं
संबंधित मुद्दे