I get input (x) from user, convert it to Int by let y = (read x)::Int and then I would like the function to behave in a special way if user gave nothing (empty string).
-- In this place I would like to handle situation in which user
-- gave empty string as argument
-- this doesnt work :/
yearFilter [] y = True
--This works fine as far as y is integer
yearFilter x y | x == (objectYear y) = True
| otherwise = False
Thanks for help, Bye
Perhaps you want a Maybe
type? If the user enters the empty string, your function returns Nothing
; otherwise it returns Just n
, where n
is what's entered by the user?
userInt :: String -> Maybe Int
userInt [] = Nothing
userInt s = Just $ read s
(I haven't compiled this code.)
In this case, Maybe
may not suffice: You have three conditions to worry about:
This data type and function express this directly:
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
Note that rather than using the incomplete function read
, it uses reads
which will not error on input which cannot be converted. reads
has a somewhat awkward interface, alas, so I almost always end up wrapping it in a function that returns Maybe a
or something like this here.
Example use:
> input "42" :: Input Int
Input 42
> input "cat" :: Input Int
BadInput "cat"
> input "" :: Input Int
NoInput
I would code your yearFilter
function like this:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter Nothing _ = True
yearFilter (Just x) y = x == objectYear y
Then I'd handle user input as:
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) ....
N.B.: I've cleaned up the code in yearFilter
a bit: no need to use guards to produce a boolean from a test - just return the test, function application (objectYear
) binds tighter than operators (==
) so removed parenthesis, replaced names of unused inputs with _
.
Okay, I admit I can't help myself.... I've rewritten yearFilter
yet again, this time as I would be inclined to write it:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter x y = maybe True (== objectYear y) x
Learning about Maybe
and maybe
was first thing about Haskell that really made me love the language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With