Поймать исключение при индексации списка в Haskell - PullRequest
3 голосов
/ 31 мая 2011
getChar :: Int -> IO Char
getChar n = do   
    c <- getLine   
    return (c !! n)   

Программа должна иметь номер и строку, и она будет возвращать символ, но как мне перехватить исключение, если число слишком большое?

Я пытался так, но, похоже, не работает

getChar n   
   = do    
       c <-getLine   
| n>=0 && n < b   
  = return c !! n    
| otherwise    
  = error "Too big number"    
where
  b = length c

Это не домашняя работа, я пытаюсь вовлечь себя. Google не дал мне полезных ответов
Не удалось реализовать поймать там. Примеры?

Ответы [ 3 ]

8 голосов
/ 31 мая 2011

Вы, вероятно, хотите немного реструктурировать вещи, так как у вас есть IO, перепутанный с чем-то, что не должно быть. Как насчет изменения подписи на что-то вроде этого?

getChar :: Int -> String -> Maybe Char
getChar n x | n < length x = Just (x !! n)
            | otherwise = Nothing

Data.Maybe позволяет указать, что вы собираетесь что-то возвращать (например, длина находится в пределах диапазона) или Nothing (длина не находится в пределах диапазона). Функция, которая вызывает getChar, может затем решить, что делать с вещами. Data.Either предоставляет способ возврата сообщения об ошибке с ошибкой. Из того, что я видел (и я ни в коем случае не эксперт), исключения редко используются в Haskell, а типы выбора, такие как Either или Maybe, используются гораздо чаще.

Теперь в коде, который вызывает это, вы можете использовать сопоставление с образцом, чтобы увидеть, что произошло, например,

main :: IO ()
main = do
  x <- getLine
  let z = getChar' 5 x
  case z of
      (Just z) -> print $ "The 5th character is " ++ show z
      Nothing -> print $ "The 5th character is out of range"
2 голосов
/ 01 июня 2011

Вы можете использовать функцию drop для удаления первых n символов строки (drop выдаст пустой результат, если число символов меньше n) и функцию listToMaybe, чтобы превратить список в a Может быть (либо Just c, где c - первый элемент списка, либо Nothing, если список пуст):

import Data.Maybe (listToMaybe)

getchar :: Int -> IO (Maybe Char)
getchar n = do
    line <- getLine
    return . listToMaybe . drop n $ line
1 голос
/ 31 мая 2011
getChar' :: Int -> IO Char
getChar' n = 
    do
            c <- getLine
            if (n < length c)
               then
                    return (c !! n)
               else
                    getChar' n

Вы можете сделать что-то, как указано выше.Это всего лишь пример, хотя.Но, поскольку вы новичок, настоятельно рекомендуется не играть с IO и Monads.Вы можете прийти к нему после ознакомления с чисто функциональными концепциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...