2011-02-25 16 views
17

मेरे हास्केल प्रोग्राम में, मैं tuples की सूची को प्रारूपित करने के लिए printf का उपयोग करना चाहता हूं। मैं एक सूची पर printf मैप कर सकते हैं इस तरह एक बार में मूल्यों एक बाहर मुद्रित करने के लिए:हास्केल में तर्क के रूप में फ़ंक्शन में टुपल के तत्वों को फ़ीड करें?

mapM_ (printf "Value: %d\n") [1,2,3,4] 

Value: 1 
Value: 2 
Value: 3 
Value: 4 

मैं इस तरह कुछ करने के लिए सक्षम होना चाहते हैं:

mapM_ (printf "Values: %d %d\n") [(1,100),(2,350),(3,600),(4,200)] 

Values: 1 100 
Values: 2 350 
Values: 3 600 
Values: 4 200 

लेकिन यह करने के लिए एक टपल गुजरता printf, दो अलग मूल्य नहीं। मैं printf के लिए दो तर्कों में टुपल कैसे बदल सकता हूं?

+0

संबंधित http://stackoverflow.com/q/6237259/168034 – phunehehe

उत्तर

36

फ़ंक्शन uncurry जोड़े पर एक फ़ंक्शन में दो-तर्क (करीबी) फ़ंक्शन को परिवर्तित करता है।

uncurry :: (a -> b -> c) -> (a, b) -> c 

आप printf पर इसका इस्तेमाल करने की जरूरत है इस तरह:: यहाँ अपने प्रकार हस्ताक्षर है

mapM_ (uncurry $ printf "Values: %d %d\n") [(1,100),(2,350),(3,600),(4,200)] 

एक अन्य समाधान पैटर्न टपल deconstruct करने के लिए मिलान का उपयोग करने के, इस तरह है:

mapM_ (\(a,b) -> printf "Values: %d %d\n" a b) [(1,100),(2,350),(3,600),(4,200)] 
+0

एक बेहतर विकल्प नीचे दिए गए मेरे उत्तर में प्रदर्शित प्रकार-सुरक्षित प्रारूपण पैकेज है; http://stackoverflow.com/a/32848676/235908 –

3
mapM_ (\(x,y) -> printf "Value: %d %d\n" x y) [(1,100),(2,350),(3,600),(4,200)] 
2

Text.Printf पर एक प्रकार का सुरक्षित विकल्प formatting पी है ackage। Text.Printf.printf संकलन-समय पर सुनिश्चित नहीं करता है कि स्वरूपण पैरामीटर की संख्या तर्कों और उनके प्रकारों की संख्या के साथ संरेखित होती है। उदाहरण के लिए क्रिस डोन का आलेख, What's wrong with printf? पढ़ें।

एक उदाहरण उपयोग:

{-# LANGUAGE OverloadedStrings #-} 
import Formatting 

map (uncurry $ formatToString ("Value: " % int % " " % int)) [(1,100), (2,350), ...] 
map (\(x,y) -> formatToString ("Value: " % int % " " % int) x y) [(1,100), (2,350), ...] 

यह ठीक ढंग से काम GHC विस्तार OverloadedStrings की आवश्यकता है।

जबकि formatToString ("Value: " % int % " " % int) प्रकार Int -> Int -> String है, uncurrying यह प्रकार (Int, Int) -> String जिनमें से इनपुट प्रकार सूची में तत्वों से मेल खाता है देता है।

पुनर्लेखन प्रक्रिया को तोड़ दिया जा सकता है; f = formatString ("Value: " ...),

map (\(x,y) -> f x y) ≡ map (\(x,y) -> uncurry f (x,y)) ≡ map (uncurry f) 

संभालने है, पहले आप uncurry च समारोह है कि tuples को स्वीकार करता है को प्राप्त करने, और फिर आप प्रदर्शन एक नियमित Eta-conversion\(x,y) -> uncurry f (x,y) के बाद से बस uncurry f के बराबर है। परिणाम में प्रत्येक पंक्ति को मुद्रित करने के mapM_ का उपयोग करें:

mapM_ (putStrLn . uncurry $ formatToString ...) [(1,100), (2,350), ...] 

आप hlint YourFile.hs चलाते हैं, तो इन पुनर्लेखन आप के लिए सिफारिश की जाएगी।

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