MaybeT / Maybe and IO: Failsafe Read Information

I am trying to read the information entered by the user and parse it into a type Personthat uses the type Gender. For this, I use this code:

data Person = Person String Int Gender String
data Gender = Male | Female | NotSpecified deriving Read

instance Show Gender where
    show Male = "male"
    show Female = "female"
    show NotSpecified = "not specified"

instance Show Person where
    show (Person n a g j) = "Person {name: " ++ n ++ ", age: " ++ show a ++ 
        ", gender: " ++ show g ++ ", job: " ++ j ++ "}"

readPersonMaybeT :: MaybeT IO ()
readPersonMaybeT = do
    putStrLn "Name?:"
    name <- getLine
    putStrLn "Age?:"
    ageStr <- getLine
    putStrLn "Gender?:"
    genderStr <- getLine
    putStrLn "Job?:"
    job <- getLine

    let newPerson = Person name (read ageStr) (read genderStr) job
    putStrLn $ show newPerson

Now I would like to make it more reliable - for this I tried to use the MaybeT nun. using this code, I got this code:

readPersonMaybeT :: MaybeT IO ()
readPersonMaybeT = do
    lift $ putStrLn "Name?:"
    name <- lift getLine
    lift $ putStrLn "Age?:"
    ageStr <- lift getLine
    lift $ putStrLn "Gender?:"
    genderStr <- lift getLine
    lift $ putStrLn "Job?:"
    job <- lift getLine

    let newPerson = Person name (read ageStr) (read genderStr) job
    lift $ putStrLn "show newPerson"

It receives GHCI compilation / loading, but when I try to execute a function readPersonMaybeT, I get an error

There is no instance for (Data.Functor.Classes.Show1 IO) arising from the use of `print 'In the line of the GHCi interactive command: print it

How can I solve this problem? By writing this code, I used wikibook about Monad Transformers.

EDIT: "" runMaybeT, , . , ,

Person {name: 85, age: *** : Prelude.read: no parse.

+4
1

, , IO Maybe:

import Text.Read
import Control.Monad.Trans.Maybe
import Control.Monad.IO.Class

askPerson :: IO (Maybe Person)
askPerson = do
  name <- putStr "Name? " >> getLine
  a <- putStr "Age? " >> getLine
  g <- putStr "Gender? " >> getLine
  return $ do age <- readMaybe a
              gender <- readMaybe g
              return $ Person name age gender

, Maybe return.

MaybeT, , -

askPersonT :: MaybeT IO Person
askPersonT = do
  name   <- liftIO $ putStr "Name? " >> getLine
  age    <- MaybeT $ fmap readMaybe $ putStr "Age? " >> getLine
  gender <- MaybeT $ fmap readMaybe $ putStr "Gender? " >> getLine
  return $ Person name age gender

doit = runMaybeT askPersonT

, .

+5
source

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


All Articles