2015-03-26 6 views
5

में घोषणा टाइप करें मेरे पास फ़ंक्शन का एक उदाहरण है, जिसमें मैं where खंड में एक प्रकार नहीं लिख सकता। replace एक फ़ंक्शन है, जो किसी दिए गए सूची में वाईएस द्वारा सभी एक्स को प्रतिस्थापित करता है। एक ही समय मेंहास्केल:

ProblemsArithmetics.hs:156:31: 
Could not deduce (a ~ a1) 
from the context (Eq a) 
    bound by the type signature for 
      replace :: Eq a => a -> a -> [a] -> [a] 
    at ProblemsArithmetics.hs:152:12-41 
or from (Eq a1) 
    bound by the type signature for helper :: Eq a1 => a1 -> a1 
    at ProblemsArithmetics.hs:155:15-30 
    ‘a’ is a rigid type variable bound by 
     the type signature for replace :: Eq a => a -> a -> [a] -> [a] 
     at ProblemsArithmetics.hs:152:12 
    ‘a1’ is a rigid type variable bound by 
     the type signature for helper :: Eq a1 => a1 -> a1 
     at ProblemsArithmetics.hs:155:15 
Relevant bindings include 
    el :: a1 (bound at ProblemsArithmetics.hs:156:16) 
    helper :: a1 -> a1 (bound at ProblemsArithmetics.hs:156:5) 
    xs :: [a] (bound at ProblemsArithmetics.hs:153:13) 
    y :: a (bound at ProblemsArithmetics.hs:153:11) 
    x :: a (bound at ProblemsArithmetics.hs:153:9) 
    replace :: a -> a -> [a] -> [a] 
    (bound at ProblemsArithmetics.hs:153:1) 
In the second argument of ‘(==)’, namely ‘x’ 
In the expression: el == x 

, अगर मैं छोड़

helper :: (Eq a) => a -> a 

कोड ठीक संकलित किया गया है:

replace :: (Eq a) => a -> a -> [a] -> [a] 
replace x y xs = map helper xs 
    where 
    helper :: (Eq a) => a -> a 
    helper = (\el -> if el == x then y else el) 

जब मैं इस समारोह को संकलित करने की कोशिश मैं कोई त्रुटि मिलती है।

मैं तर्क को समझते हैं इसके पीछे (areplace में प्रकार घोषणा और ahelper में प्रकार घोषणा अलग a रों कर रहे हैं), और वहाँ कम से कम 2 समाधान (छोड़ प्रकार घोषणा या helper कार्य करने के लिए x और y पैरामीटर के रूप में पारित कर रहे हैं), मेरा सवाल है:

क्या कंपाइलर को बताने का कोई तरीका है कि मेरा मतलब दोनों प्रकार की घोषणाओं में एक ही प्रकार है?

+3

हाँ: https://wiki.haskell.org/Scoped_type_variables – Jubobs

+2

जोड़ने का प्रयास करें '{- # भाषा ScopedTypeVariables # -}'। मैं अब परीक्षण नहीं कर सकता, कोई भी मेरी टिप्पणी को उत्तर में बदलने के लिए स्वतंत्र है। – Franky

उत्तर

10

यदि आप ScopedTypeVariables सक्षम करते हैं और forall के साथ एक प्रकार चर लागू करते हैं, तो यह आंतरिक दायरे में दिखाई देता है।

{-# LANGUAGE ScopedTypeVariables #-} 

replace :: forall a. (Eq a) => a -> a -> [a] -> [a] 
replace x y xs = map helper xs 
    where 
    helper :: a -> a 
    helper = (\el -> if el == x then y else el)