2013-04-08 2 views
10

मैं अक्सर अपने आप को कोड है कि इस तरह दिखता है लिख पाते हैं:में एक monadic अभिव्यक्ति दूध पिलाने की जब तक या जब

import System.Directory (doesFileExist) 
import Control.Monad (unless) 

example = do 
    fileExists <- doesFileExist "wombat.txt" 
    unless fileExists $ putStrLn "Guess I should create the file, huh?" 

शायद एक बेहतर तरीका है:

example2 = 
    doesFileExist "wombat.txt" >>= 
    (\b -> unless b $ putStrLn "Guess I should create the file, huh?") 

क्या सबसे अच्छा तरीका यहाँ है?

+5

साथ 'unless' लिए बाइंडिंग' (>> =) 'एक वर्ग के साथ किया जा सकता है,' 'कुछ >> = (' unless' someAction) '', अगर 'someAction' कम है। यदि यह छोटा नहीं है, तो मुझे लगता है कि 'बूल करें <- कुछ; जब तक कि बूल $ जो कुछ भी बेहतर न हो। –

+1

आप 'mfilter' का उपयोग कर सकते हैं, जो कि' हो सकता है 'में आपकी गणना को एम्बेड करते समय भी बेहतर काम करता है। –

उत्तर

5

मैं एक सहायक समारोह निर्धारित कर सकते हैं:

unlessM :: Monad m => m Bool -> m() -> m() 
unlessM b s = b >>= (\t -> unless t s) 

example3 = unlessM (doesFileExist "wombat.txt") $ 
    putStrLn "Guess I should create the file, huh?" 

यह unlessM की तरह लगता है बहुत उपयोगी होगा। लेकिन तथ्य यह है कि मुझे हैकेज पर unlessM (या उस प्रकार के हस्ताक्षर के साथ) कुछ भी नहीं दिखता है, मुझे लगता है कि इस स्थिति को संभालने का कुछ बेहतर तरीका है, जिसे मैंने अभी तक नहीं खोजा है। शांत बच्चे क्या करते हैं?

+2

यहां इसका एक संस्करण है: http://hackage.haskell.org/packages/archive/cond/0.4.0.2/doc/html/Control-Conditional.html#v:unlessM –

+1

वहां ['अतिरिक्त'] (https है : //hackage.haskell.org/package/extra-1.6/docs/Control-Monad-Extra.html) पैकेज जो 'tillM' भी प्रदान करता है और अधिक सक्रिय रूप से बनाए रखा प्रतीत होता है। –

5

मैंने ऐसे मामलों के लिए flip unless का उपयोग किया है, लेकिन इन प्रकार के संयोजकों को थोड़ा शोर मिल सकता है। LambdaCase एक्सटेंशन के साथ, आप कम से कम doesFileExist के परिणाम के लिए नाम का उपयोग करने से बच सकते हैं, हालांकि इसके परिणामस्वरूप True और False पर पैटर्न मिलान हो सकता है, जो थोड़ा अजीब लग सकता है (यदि आप मानते हैं कि if अनावश्यक है या नहीं)।

{-# LANGUAGE LambdaCase #-} 
import System.Directory (doesFileExist) 
import Control.Monad (unless) 

example' = 
    doesFileExist "wombat.txt" >>= 
    flip unless (putStrLn "Guess I should create the file, huh?") 

example'' = 
    doesFileExist "wombat.txt" >>= \ case 
    True -> return() 
    False -> putStrLn "Guess I should create the file, huh?" 
संबंधित मुद्दे