Sto utilizzando il pacchetto Haskeline e voglio ottenere tre stringhe in fila dalla riga di comando prima di fare qualsiasi cosa e ho trovato quella che sembra essere una soluzione pulita per me . Ma sono sicuro che potrebbe esserci un modo migliore per farlo. Sto cercando le migliori pratiche durante l'utilizzo del pacchetto Haskeline. Si prega di valutare i meriti del seguente codice di esempio:Haskell Best Practice: terminazione anticipata in 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)
Come si può vedere si compia il compito di scioglimento anticipato, ma sembra un po 'schifo ancora. Sto pensando di provare a convertire il notNothing del ei getInputLine di in un'unica linea come:
mone <- notNothing =<< lift $ getInputLine "food> " -- does not type check
Che credo non sembra poi così male. Penso che sia abbastanza chiaro e conciso (sebbene non scriva check, quindi dovrò scrivere una versione che lo faccia).
Tuttavia, questo è il migliore che ho trovato e alla fine la mia domanda è: come procedere per migliorare questo codice per essere più ordinato e più leggibile? Sono sulla buona strada?
Edit: se la guardia è qualcosa di diverso da 'A/= Nothing' quindi una bella funzione di supporto che ho appena scoperto è:
myGuard s = guard (someConditionFunc s) >> s
perché allora si può scrivere (come luqui suggerito):
mone <- myGuard =<< (lift $ getInputLine prompt)
Che è bello. Ma se stai confrontando solo con Nothing, la risposta di TomMD è migliore.
Penso che la tua linea combinata non funzioni a causa della precedenza di '$'; prova 'mone <- notNothing = << lift (getInputLine" cibo> ")' –
Se sei interessato alle best practice in generale, dovresti usare hlint sul tuo codice. – amccausl
@amccausl Lo faccio ma non avrebbe suggerito questo non penso. –