NILL оценивают в haskell

Я ввожусь (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

Спасибо за справку, До свидания

5
задан Ionuț G. Stan 28 May 2010 в 23:45
поделиться

4 ответа

Функция read не может преобразовать пустую строку в int и вызовет ошибку, если вы попытаетесь это сделать. Вам нужно будет проверить, является ли ввод пустой строкой перед преобразованием в int. Если вы хотите использовать значение по умолчанию (например, 0) в том случае, если пользователь вводит пустую строку, вы можете сделать что-то вроде этого:

let y = if null x then 0 else read x
2
ответ дан 18 December 2019 в 06:49
поделиться

В этом случае Возможно может быть недостаточно: У вас есть три условия, о которых нужно беспокоиться:

  1. Пользователь ничего не ввел
  2. Пользовательский ввод был действительным
  3. Пользовательский ввод был непарсируемым

Этот тип данных и функция выражают это напрямую:

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, которая действительно заставила меня полюбить язык.

4
ответ дан 18 December 2019 в 06:49
поделиться

Не существует 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"
3
ответ дан 18 December 2019 в 06:49
поделиться

Возможно, вам нужен тип Maybe? Если пользователь вводит пустую строку, ваша функция возвращает Nothing; в противном случае она возвращает Just n, где n - это то, что ввел пользователь?

userInt :: String -> Maybe Int
userInt [] = Nothing
userInt s  = Just $ read s

(Я не компилировал этот код.)

.
14
ответ дан 18 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: