2013-07-04 7 views
15

Dziś znalazłem się wpisując następujący kod:Korzystanie sprawę dla multi-way jeśli

case() of 
    _ | x < 15 -> ... 
    _ | x < 25 -> ... 
    _ | x < 50 -> ... 
    _   -> ... 

Sens tego jest na tyle prosta, ale po prostu czuje ... źle wypowiedzieć case(). Czy ktokolwiek ma lepszą sugestię?

Przypuszczam, że ponieważ jestem branding na x, mógłbym napisać case x. Ale to nadal nie pozostawia mi nic do faktycznego dopasowania; chodzi tylko o strażników. I to wciąż wydaje się dziwne.

+2

Co o [Multi-way jeśli] (http://www.haskell.org/gh c/docs/7.6.2/html/users_guide/syntax-extns.html # multi-way-if) w nowszych wersjach GHC? – Vitus

+6

Czy coś jest nie tak z funkcją? 'f x | x <15 = ...; | x <25 = ...; ... ' –

Odpowiedz

14

Nie ma nic złego w case(); Jest to najlepsze rozwiązanie dla tego przypadku użycia, chyba że chcesz używać najnowszych składniowych i niestandardowych rozszerzeń, takich jak GHC multi-way-if.

14

Inni wspomnieć, że case jeśli dobrze i mutli sposób, jeśli istnieje, ale chcę iść do lokalnego funkcji poprzez gdzie i niech stwierdzenie:

someFunction = do 
    x <- monadicOp 
    let f y | y < 5 = expr1 
      | y < 15 = expr2 
      | y < 25 = expr3 
      | True = expr4 
    f x 

To składniowo czystsze niż rozwiązania case i bardziej przenośny niż wielozadaniowy, jeśli.

EDIT:

W przypadku, gdy nie jest jasne, czy wartość porównywana, x w tym przypadku, to już w zasięgu podczas definiowania funkcji strzeżony (f), a następnie można po prostu zdefiniować wartość zamiast :

someFunction = do 
    x <- monadicOp 
    let r | x < 15 = expr1 
      | x < 25 = expr2 
    r 
+0

Gdyby tylko jeden nie musiał wymyślić nazwy dla" r ", byłoby wspaniale. –

+0

Czy powinniśmy utworzyć rozszerzenie LambdaMultiWayIf? –

+0

Wielokierunkowe, jeśli w rzeczywistości nie ma skrutowanej osoby. Więc co chcesz zrobić z anonimową argumentacją? –

2

można wykorzystać ocenę leniwy, aby wymyślić coś takiego:

import Data.List 
import Data.Maybe 
import Control.Applicative 

cases :: [(Bool,a)] -> a -> a 
cases lst d = snd $ fromJust $ (find fst lst) <|> Just (True,d) 

main = do 
    let x = 20 
     r = cases [(x < 15, putStr "15"), 
       (x < 25, putStr "25"), 
       (x < 50, putStr "50")] $ putStr "None" 
    in 
     r 
+0

Możesz także użyć do tego celu spisu, jak w "concat $ [[putStrLn" 15 "| x <15], [putStrLn" 25 "| x <" 25 "], ...] – bennofs

+4

Również' fromJust $ x <|> Just y' to dość skomplikowany sposób pisania 'fromMaybe yx' –

Powiązane problemy