2011-01-22 18 views
5

में प्रारंभिक समाप्ति मैं Haskeline पैकेज का उपयोग कर रहा हूं और मैं कुछ भी करने से पहले कमांड लाइन से तीन स्ट्रिंग प्राप्त करना चाहता हूं और मैं अपने साथ एक साफ समाधान प्रतीत होता हूं । लेकिन मुझे यकीन है कि ऐसा करने का एक बेहतर तरीका हो सकता है। मैं हास्कलाइन पैकेज का उपयोग करते समय सर्वोत्तम प्रथाओं की तलाश में हूं। निम्न उदाहरण कोड की खूबियों का मूल्यांकन करें:हास्केल बेस्ट प्रैक्टिस: हास्कलाइन

import System.Console.Haskeline 
import Control.Monad.Trans 
import Control.Monad.Maybe 
import Data.Maybe 
import Control.Monad 

main :: IO() 
main = runInputT defaultSettings (runMaybeT getStrings) >>= print 

getStrings :: MaybeT (InputT IO) (String, String, String) 
getStrings = do 
    mone <- lift $ getInputLine "food> " 
    notNothing mone 
    mtwo <- lift $ getInputLine "drink> " 
    notNothing mtwo 
    mthree <- lift $ getInputLine "dessert> " 
    notNothing mthree 
    return (fromJust mone, fromJust mtwo, fromJust mthree) 
     where 
     notNothing a = guard (a /= Nothing) 

आप देख सकते हैं यह जल्दी समाप्ति का कार्य पूरा करता है लेकिन यह अभी भी एक सा yucky लग रहा है।

mone <- notNothing =<< lift $ getInputLine "food> " -- does not type check 

कौन सा मुझे लगता है कि बुरा नहीं दिखता है: मैं की तरह एक ही पंक्ति में notNothing की और getInputLine के कन्वर्ट करने के लिए कोशिश कर रहा है के बारे में सोच रहा हूँ। मुझे लगता है कि यह बहुत स्पष्ट और संक्षिप्त है (हालांकि यह चेक टाइप नहीं करता है इसलिए मुझे एक ऐसा संस्करण लिखना होगा जो करता है)।

बहरहाल, यह सबसे अच्छा मैं के साथ आए हैं अंत में है और मेरा सवाल यह है: आप neater और अधिक आसानी से पठनीय होने के लिए इस कोड को सुधारने के बारे में कैसे जाना होगा? क्या मैं सही रास्ते पर भी हूं?

संपादित: अपने गार्ड अलावा कुछ 'एक/= कुछ भी नहीं है' तो एक अच्छा सहायक समारोह है कि मैं सिर्फ पता चला है की तुलना में यह है:

myGuard s = guard (someConditionFunc s) >> s 

क्योंकि तो आप (luqui के रूप में सुझाव) लिख सकते हैं:

mone <- myGuard =<< (lift $ getInputLine prompt) 

जो बहुत अच्छा है। लेकिन अगर आप केवल कुछ भी नहीं कर रहे हैं तो टॉमएमडी का जवाब बेहतर है।

+0

मुझे लगता है कि अपने संयुक्त लाइन '' $ के पूर्वता की वजह से काम नहीं करता है; कोशिश 'मोने <- notNothing = << लिफ्ट (getInputLine" खाद्य> ")' –

+0

आप सामान्य रूप में सर्वोत्तम प्रथाओं में रुचि रखते हैं, तो आप अपने कोड पर hlint उपयोग करना चाहिए। – amccausl

+0

@amccausl मैं करता हूं लेकिन यह सुझाव नहीं दिया होता कि मुझे नहीं लगता। –

उत्तर

7

क्यों न सिर्फ इस तथ्य का लाभ उठाने कि हो सकता है कि इकाई के लिए fail _ = Nothing?

mthree <- lift $ getInputLine "dessert> " 
notNothing mthree 

Just mthree <- lift $ getInputLine "dessert> " 
+0

बहुत अच्छा !! यह पीछे की ओर में अंधेरे से स्पष्ट लगता है! कोई और उत्कृष्ट सुझाव? (हालांकि मुझे शक है यह बहुत छोटे की तुलना में यह अब है प्राप्त कर सकते हैं) –

+0

luqui: 'fail', धन्यवाद। मैं 'त्रुटि' एड। –

4

कैसे एक सहायक समारोह के बारे में हो जाता है?

inputLine :: String -> MaybeT (InputT IO) String 
inputLine prompt = do 
    m <- lift $ getInputLine prompt 
    case m of 
     Just x -> return x 
     Nothing -> mzero 

इसे विभिन्न चालों का उपयोग करके काफी कम किया जा सकता है, लेकिन मैं स्पष्ट होना चाहता था। अब आप भूल सकते हैं कि getInputLine असफल हो सकता है, MaybeT आपके लिए इसका ख्याल रखता है।

+0

आपका अधिकार! सबसे अच्छा सहायक समारोह (IMO) है 'myGuard एक = गार्ड (condition_with_a) >> वापसी एक' क्योंकि तब आप कह सकते हैं 'मी <- myGuard = << (लिफ्ट $ getInputLine शीघ्र)' –

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