2013-04-08 13 views
10

często znaleźć samodzielnie pisania kodu, który wygląda tak:Karmienie jednowartościowy wyraz w chyba albo gdy

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

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

Być może lepszym sposobem jest:

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

Co to jest najlepszym podejściem tutaj?

+5

Wiązanie z 'chyba że' z '(>> =)' można wykonać za pomocą sekcji, '' coś >> = ('chyba że 'someAction)' ', jeśli' someAction' jest krótkie. Jeśli nie jest krótki, myślę, że 'do bool <- coś; chyba że bool $ cokolwiek "jest lepsze". –

+1

Możesz użyć 'mfilter', który działa jeszcze lepiej, jeśli osadzisz swoje obliczenia w' MaybeT'. –

Odpowiedz

5

mogę zdefiniować funkcję pomocniczą:

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?" 

Wydaje się unlessM byłby bardzo przydatny. Ale fakt, że nie widzę czegoś takiego jak unlessM (lub z tym typem podpisu) w Hackage, pozwala mi sądzić, że istnieje lepszy sposób na rozwiązanie tej sytuacji, której jeszcze nie odkryłem. Co robią te fajne dzieciaki?

+2

Oto jego wersja: http://hackage.haskell.org/packages/archive/cond/0.4.0.2/doc/html/Control-Conditional.html#v:unlessM –

+1

There's the ['extra'] (https) : //hackage.haskell.org/package/extra-1.6/docs/Control-Monad-Extra.html), który również dostarcza 'unlessM' i wydaje się być bardziej aktywnie utrzymywany. –

5

Do takich przypadków użyłem flip unless, ale tego typu kombinatory mogą być trochę hałaśliwe. Z rozszerzeniem LambdaCase możesz przynajmniej unikać używania nazwy dla wyniku doesFileExist, ale może to skutkować koniecznością dopasowania wzorców na True i False, co może wyglądać trochę dziwnie (w zależności od tego, czy uważasz, że if jest niepotrzebne czy nie).

{-# 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?" 
Powiązane problemy