En este caso, Maybe
puede no ser suficiente: Usted tiene tres condiciones de las que preocuparse:
- El usuario introduce nada
- La entrada del usuario era válida
- La entrada del usuario no se pudo analizar
Este tipo de datos y la función expresan esta directamente:
data Input a = NoInput | Input a | BadInput String
deriving (Eq, Show)
input :: (Read a) => String -> Input a
input "" = NoInput
input s =
case filter (null.snd) (reads s) of
((a,_):_) -> Input a
otherwise -> BadInput s
Tenga en cuenta que en lugar de utilizar la función incompleta read
, utiliza reads
que no error en la entrada que no se pueden convertir. reads
tiene una interfaz algo incómoda, por desgracia, así que casi siempre termino envolviéndolo en una función que devuelve Maybe a
o algo así aquí.
Ejemplo del uso:
> input "42" :: Input Int
Input 42
> input "cat" :: Input Int
BadInput "cat"
> input "" :: Input Int
NoInput
que sería el código de su función yearFilter
así:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter Nothing _ = True
yearFilter (Just x) y = x == objectYear y
entonces yo manejar la entrada de usuario como:
inputToMaybe :: Input a -> Maybe a
inputToMaybe (Input a) = Just a
inputToMaybe _ = Nothing
do
a <- input `fmap` getLine
case a of
BadInput s -> putStrLn ("Didn't understand " ++ show s)
otherwise -> ... yearFilter (inputToMaybe a) ....
NB : He limpiado el código en yearFilter
un poco: no hay necesidad de usar guardias para producir un booleano de una prueba - simplemente devuelva la prueba, la aplicación de función (objectYear
) se une más estrechamente que los operadores (==
) para quitar los paréntesis, reemplazó los nombres de las entradas no utilizadas con _
.
De acuerdo, admito que no puedo ayudar yo .... Yo he reescrito yearFilter
una vez más, esta vez como me inclinaría a escribirlo:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter x y = maybe True (== objectYear y) x
Aprender sobre Maybe
y maybe
fue lo primero sobre Haskell que realmente me hizo amar el lenguaje.
Por favor, no enseñe a las personas 'longitud x == 0'. La forma idiomática y performante de escribir esta prueba es 'null x'. –
En cuanto a ser idiomático, punto tomado. Dada la definición de 'longitud', no puedo creer que haya alguna diferencia en perf. En cualquier caso, estoy un poco sorprendido de que alguien haya sentido la necesidad de votar. –
"longitud" recorrerá la cadena hasta el final para averiguar la longitud, y si esa cadena tiene 400203209 caracteres, tiene un problema de rendimiento. "nulo" se ejecutará en tiempo constante, porque solo necesita ver si hay al menos UN elemento ahí. – LukeN