Identification and elimination of exceptions

I still get jealousy from haskell and try to create my first "real" coding project, that is, where I am going to enable testing, write documentation, etc. I'm quite new to haskell where I know that I don’t have much knowledge of the required language, so all I want to do is within reach, but such an idea, so that the act of completion will require me to touch most of the main parts of the language .

In any case, so the current problem I am facing is about throwing and throwing exceptions in the language, what I understand can be done with a variety of approaches. I have a function here, toLower:

toLower :: String -> String
toLower plaintext =
  if (catch (nonAlpha plaintext) handlerNonAlpha)
  then map charToLower plaintext
  else exitFailure

Which will take the string will throw an exception and throw if the string contains any non-alpha characters (so if not AZ or az), or if the string is not converted to lowercase. So, what do I have for the nonAlpha function:

--- detect non-alpha character - throw error if existant
data NonNumericException = NonNumException

instance Exception NonNumericException

handlerNonAlpha :: NonNumericException -> IO()
handlerNonAlpha ex =
  putStrLn "Caught Exception: " ++ (show ex) ++ " - A non-alpha character was included in the plaintext."

nonAlpha :: String -> Bool
nonAlpha str =
  let nonalphas = [x | x <- str, (ord x) < 65 || (90 < (ord x) && (ord x) < 97) || 123 < (ord x)]
  in if (length nonalphas) == 0
     then True
     else throw NonNumException

As I said, I'm pretty new to haskell, so I'm a little vague about how this data / instance structure works, but as I understand it, I define a parent NonNumericException of which NonNumException is a child (and I could have more) , and in the instance line that defines them as Exceptions. The catch structure, if it catches an exception (for example, when you throw nonAlpha at the end, if there is a non-alphanumeric character), then calls the handler.

So, here are the compilation errors that I get:

utilities.hs:61:3:
Couldn't match expected type `[Char]' with actual type `IO ()'
In the return type of a call of `putStrLn'
In the first argument of `(++)', namely
  `putStrLn "Caught Exception: "'
In the expression:
  putStrLn "Caught Exception: "
  ++
    (show ex)
    ++ " - A non-alpha character was included in the plaintext."

utilities.hs:61:3:
Couldn't match expected type `IO ()' with actual type `[Char]'
In the expression:
  putStrLn "Caught Exception: "
  ++
    (show ex)
    ++ " - A non-alpha character was included in the plaintext."
In an equation for `handlerNonAlpha':
    handlerNonAlpha ex
      = putStrLn "Caught Exception: "
        ++
          (show ex)
          ++ " - A non-alpha character was included in the plaintext."

utilities.hs:73:7:
Couldn't match expected type `Bool' with actual type `IO ()'
In the return type of a call of `catch'
In the expression: (catch (nonAlpha plaintext) handlerNonAlpha)
In the expression:
  if (catch (nonAlpha plaintext) handlerNonAlpha) then
      map charToLower plaintext
  else
      exitFailure

utilities.hs:73:14:
Couldn't match expected type `IO ()' with actual type `Bool'
In the return type of a call of `nonAlpha'
In the first argument of `catch', namely `(nonAlpha plaintext)'
In the expression: (catch (nonAlpha plaintext) handlerNonAlpha)

utilities.hs:75:8:
Couldn't match type `IO a0' with `[Char]'
Expected type: String
  Actual type: IO a0
In the expression: exitFailure
In the expression:
  if (catch (nonAlpha plaintext) handlerNonAlpha) then
      map charToLower plaintext
  else
      exitFailure
In an equation for `toLower':
    toLower plaintext
      = if (catch (nonAlpha plaintext) handlerNonAlpha) then
            map charToLower plaintext
        else
            exitFailure

, , : ) ( 61) b) , , bool ?

EDIT: , . , . , , , - , , .

+4
2

Haskell, , / . , , - toLower . :

-- We can factor out our check for a non-alpha character
isNonAlpha :: Char -> Bool
isNonAlpha c = c' < 65 || (90 < c' && c' < 97) || 123 < c'
    where c' = ord c

-- Why throw an exception? Just return False
hasNonAlpha :: String -> Bool
hasNonAlpha str = any isNonAlpha str

-- Renamed to not conflict with Data.Char.toLower
myToLower :: String -> Maybe String
myToLower plaintext =
    if hasNonAlpha plaintext
        then Nothing
        else Just $ map toLower plaintext

, , - , , . . , Maybe:

doSomething :: String -> String -> Maybe String
doSomething s1 s2 = do
    s1Lower <- myToLower s1
    s2Lower <- myToLower s2
    return $ s1Lower ++ s2Lower

myToLower s1, myToLower s2 Nothing, doSomething Nothing. , . Haskell , , throw, catch, IO. IO . , throw, .


, myToLower

import Control.Monad

-- Other code

myToLower :: String -> Maybe String
myToLower plaintext = do
    guard $ not $ hasNonAlpha plaintext
    return $ map toLower plaintext

guard Control.Monad MonadPlus. Maybe MonadPlus ( ), .

, :

type MyError = String

myToLower :: String -> Either MyError String
myToLower plaintext = if hasNonAlpha plaintext
    then Left  $ "The string " ++ plaintext ++ " has non-alpha character(s)"
    else Right $ map toLower plaintext

doSomething, :

doSomething :: String -> String -> Either MyError String
doSomething s1 s2 = do
    s1Lower <- myToLower s1
    s2Lower <- myToLower s2
    return $ s1Lower ++ s2Lower

, , ! , , .

+5

, .

, . " Haskell" - .

.

61

handlerNonAlpha :: NonNumericException -> IO()
handlerNonAlpha ex =
  putStrLn "Caught Exception: " ++ (show ex) ++ ...

haskell. , putStrLn:

putStrLn $ "Caught Exception: " ++ (show ex) ++ ...

nonAlpha

IO, . , nonAlpha , , Bool, True, . False?

nonAlpha :: String -> Bool
nonAlpha str =
  let nonalphas = [x | x <- str, (ord x) < 65 || (90 < (ord x) && (ord x) < 97) || 123 < (ord x)]
  in if (length nonalphas) == 0
     then True
     else False

nonAlpha . , :

trapInvalid :: String -> IO ()
trapInvalid str = unless (nonAlpha str) $ throw NonNumException
+1

Source: https://habr.com/ru/post/1534516/


All Articles