Я ввожусь (x) от пользователя, преобразуйте его в Интервал y, которому позволяют, = (считайте x):: Интервал и затем я хотел бы, чтобы функция вела себя специальным способом, если бы пользователь ничего не дал (пустая строка).
-- 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
Спасибо за справку, До свидания
Функция read не может преобразовать пустую строку в int и вызовет ошибку, если вы попытаетесь это сделать. Вам нужно будет проверить, является ли ввод пустой строкой перед преобразованием в int. Если вы хотите использовать значение по умолчанию (например, 0) в том случае, если пользователь вводит пустую строку, вы можете сделать что-то вроде этого:
let y = if null x then 0 else read x
В этом случае Возможно
может быть недостаточно: У вас есть три условия, о которых нужно беспокоиться:
Этот тип данных и функция выражают это напрямую:
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
Обратите внимание, что вместо использования неполной функции read
здесь используется reads
, которая не будет ошибаться при вводе, который не может быть преобразован. reads
, увы, имеет несколько неудобный интерфейс, поэтому я почти всегда в конечном итоге оборачиваю ее в функцию, которая возвращает Maybe a
или что-то вроде этого здесь.
Пример использования:
> input "42" :: Input Int
Input 42
> input "cat" :: Input Int
BadInput "cat"
> input "" :: Input Int
NoInput
Я бы закодировал вашу функцию yearFilter
следующим образом:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter Nothing _ = True
yearFilter (Just x) y = x == objectYear y
Затем я бы обработал ввод пользователя следующим образом:
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. Я немного почистил код в yearFilter
: не нужно использовать гварды для получения булевого значения из теста - просто верните тест, применение функции (objectYear
) связывается сильнее, чем операторы (==
), поэтому убрал скобки, заменил имена неиспользуемых входов на _
.
Ладно, признаю, я не могу удержаться. Я снова переписал yearFilter
, на этот раз так, как я был бы склонен его написать:
yearFilter :: Maybe Int -> Int -> Bool
yearFilter x y = maybe True (== objectYear y) x
Изучение Maybe
и maybe
было первой вещью в Haskell, которая действительно заставила меня полюбить язык.
Не существует NULL, если вы явно его не определите. Вы можете проверить пустые строки следующим образом.
readInput :: IO ()
readInput = do
ln <- getLine
if valid ln
then -- whatever
else -- whatever
valid x
| null x = False
| not istJust convert x = False
| otherwise = True
where convert :: String -> Maybe Int
convert = fmap fst $ listToMaybe . reads $ "f"
Возможно, вам нужен тип Maybe
? Если пользователь вводит пустую строку, ваша функция возвращает Nothing
; в противном случае она возвращает Just n
, где n
- это то, что ввел пользователь?
userInt :: String -> Maybe Int
userInt [] = Nothing
userInt s = Just $ read s
(Я не компилировал этот код.)
.