2015-12-09 2 views
0

Я новичок в Haskell, и я не могу получить код правильно.Проверка наличия строки в верхнем регистре

Я пробовал:

identifier :: String -> String 
identifier input 
    | isUpper input == True = putStrLn("*** Exception: Uppercase" ++ input) 
    | return input 

И моя последняя попытка была:

identifier :: String -> String 
identifier input = do 
    if isUpper input == True 
     then putStrLn("*** Exception : Uppercase" ++ input) 
     else return input 

Он должен возвращать сообщение исключения, когда вход содержит заглавную букву. И верните ввод, если он строчный или любой другой символ. Может кто-нибудь может предложить лучший способ написать это?

+0

Style комментарий: нет необходимости писать 'что-то == true', так что эквивалентно просто' something'. Это также эквивалентно '(что-то == True) == True', но вы бы этого не писали, не так ли? ;-) – chi

ответ

3

, если вы хотите включить "нормальный" ввод/вывод, который вы должны сделать вашу функцию

identifier :: String -> IO String 

в противном случае (даже если это не очень хорошая привычка писать небезопасные функции) Я рекомендую использовать error "*** Exception …" (если вы хотите использовать реальные исключения взглянуть на Control.Except и MonadThrow/MonadCatch

рядом. - Яssume isUpper импортируется из Data.Char и работает только с персонажами. Я хотел бы объединить isUpper с функцией all, которая проверяет, является ли свойство (здесь isUpper) истинным для всех элементов списка, которое может быть применено к String, поскольку это просто синоним для [Char]. Я также рекомендую не проверять верхний, но строчный регистр, поскольку это ваша цель.

так что вы можете иметь что-то вроде

if (all isLower input) 
    then input 
    else error "i will promise to look at Data.Maybe and Data.Either in the near future" 
3

Он должен вернуть сообщение об исключении, если вход содержит прописную букву. И верните ввод, если он является строчным или любым другим символом. Может кто-нибудь может предложить лучший способ написать это?

  • избегать функций, которые бросают исключения и производят побочные эффекты, когда они могут быть написаны purely.
  • putStrLn ("*** Exception: ...") не будет производить исключения. error "Uppercase" будет.

Если функция имеет подпись String -> String, она не может

  • использование isUpper на входе, так Data.Char.isUpper :: Char -> Bool или
  • использование putStrLn как выход, так как System.IO.putStrLn :: String -> IO().

Если единственным критерием для действительного идентификатора является то, что он не содержит прописные latters, вы могли бы написать:

isIdentifier :: String -> Bool 
isIdentifier = not . any isUpper 

хотя вы, вероятно, хотите, чтобы сформулировать все критерии допустимых идентификаторов в качестве одного предиката. Это может быть, например, соответствие что-то вроде [_a-Z] [_ A-Za-Z0-9] +:

isIdentifier :: String -> Bool 
isIdentifier (c:cs) = (c == '_' || isLower c) && all (\c -> c == '_' || isAlphaNum c) cs 
isIdentifier "" = False 
+0

Я думаю, что ваша функция «идентификатор» проверяет только первую букву «String» и никого другого - так что это не даст правильного результата для «d'Artagnan». Я думаю, что вы должны вызывать 'isIdentifier' рекурсивно или использовать' fold' – epsilonhalbe

+0

Я исправил это, спасибо. –

Смежные вопросы