2012-01-30 9 views
23

रिकॉर्ड के पैटर्न मिलान के बारे में हास्केल विकी पर अपेक्षाकृत संक्षिप्त पाठ के बाद, मुझे यकीन नहीं है कि रिकॉर्ड के फ़ील्ड को कुछ मूल्य के साथ मिलान किया जा सकता है और एक ही समय में पैरामीटर को असाइन किया जा सकता है।क्या रिकॉर्ड का फ़ील्ड कुछ मूल्य के साथ मिलान किया जा सकता है और एक ही समय में पैरामीटर को असाइन किया जा सकता है?

-- Sample record type 
data Rec = Rec { uid :: Int, name :: String } 

-- Function to update Rec's fields 
updateRec :: Rec -> Rec 

-- basic matching with record data constructor 
updateRec (Rec _ []) = Rec 0 "Nobody" 

-- dtto with as-pattern at 2nd param 
updateRec (Rec idn [email protected]"Alice") = Rec (idn+1) (ns ++ "+1") 

-- basic matching by fields values 
updateRec Rec {name = "Bob", uid = 42} = Rec (10^6) "SuperBob" 

-- Q: how to match by name field and assign it's value ? 
updateRec Rec {name = "Bob", uid = idn} = 
    Rec {uid = (idn+1), name = ("Bob" ++ "+1")} 

-- Q: as-pattern works only on the whole record, not on a field 
updateRec [email protected](Rec {name = "Bob", uid = idn}) = 
    Rec {uid = (idn+1), name = (name reC++ "+1")} 

-- Q: pattern guards do work, but they are a bit clumsy 
updateRec Rec {name = uname, uid = idn} 
    | uname == "Bob" = Rec {uid = (idn+1), name = (uname ++ "+1")} 
    | otherwise = ... 

तो वहाँ पैटर्न मैच के लिए कुछ संक्षिप्त तरीके से रिकॉर्ड के क्षेत्र से है और एक ही समय में अपने मूल्य आवंटित?

नोट: मैं विशिष्ट जीएचसी के एक्सटेंशन से बचना चाहता हूं।

उत्तर

29

फ़ील्ड नाम, पैटर्न खुद को कर रहे हैं तो आप उपयोग कर सकते हैं एक और के रूप में पैटर्न:

updateRec Rec {name = [email protected]"Bob", uid = [email protected]} = ... 

इस, मानक या साथ GHC एक्सटेंशन करने के लिए कोई अधिक संक्षिप्त तरीका नहीं है। बेशक, इस मामले के रूप में सरल के लिए, आप बस बाइंडिंग को छोड़ सकते हैं और "Bob" और 42 सीधे फ़ंक्शन बॉडी में उपयोग कर सकते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे