haskell - MaybeT/Maybe and IO: Failsafe reading of information -


i trying read information entered user , parse type person, uses type gender. so, use code:

data person = person string int gender string data gender = male | female | notspecified deriving read  instance show gender     show male = "male"     show female = "female"     show notspecified = "not specified"  instance show person     show (person n g j) = "person {name: " ++ n ++ ", age: " ++ show ++          ", gender: " ++ show g ++ ", job: " ++ j ++ "}"  readpersonmaybet :: maybet io () readpersonmaybet =     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 make more failsafe - achieve tried use maybet monad. using this, got code:

readpersonmaybet :: maybet io () readpersonmaybet =     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 compiles/loaded ghci, when try execute readpersonmaybet function error-message

no instance (data.functor.classes.show1 io) arising use of `print' in stmt of interactive ghci command: print it

how can solve issue? writing code, used wikibook monad transformers.

edit: when try 'run' runmaybet gets executed, not failsafe @ all. entering nonsense age example still results in output like

person {name: 85, age: *** exception: prelude.read: no parse.

share|improve question
    
how did 'execute' it? did use runmaybet ? – pdexter aug 8 '16 @ 14:04
    
no, did not know, have call runmaybet... tried now, , did not solve real problem (see edit). – flashtek aug 8 '16 @ 14:10
    
you should show definition of person – erikr aug 8 '16 @ 14:12
    
you want use readmaybe – pdexter aug 8 '16 @ 14:13
    
ps. note you're lifting every operation inside do block. you're never doing in actual maybe monad. – pdexter aug 8 '16 @ 14:23
up vote 5 down vote accepted

if doing validation after have asked of input, use io monad , return maybe:

import text.read import control.monad.trans.maybe import control.monad.io.class  askperson :: io (maybe person) askperson =   name <- putstr "name? " >> getline   <- putstr "age? " >> getline   g <- putstr "gender? " >> getline   return $ age <- readmaybe               gender <- readmaybe g               return $ person name age gender 

note how using maybe monad in return statement.

i use maybet if want quit asking input once enter invalid value --

askpersont :: maybet io person askpersont =   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 

if user enters invalid age won't asked gender.

share|improve answer
1  
in first, return (person <$> pure name <*> readmaybe <*> readmaybe g) idiomatic, think. in second can use applicative-style, prefer wrote since each line nontrivial. – chi aug 8 '16 @ 16:08
    
the pure in comment confuses me. aren't in right context usr of return , fmap? – amalloy aug 8 '16 @ 16:10
    
oh, now. missed going on readmaybe calls. – amalloy aug 8 '16 @ 16:14

your answer

 
discard

posting answer, agree privacy policy , terms of service.

not answer you're looking for? browse other questions tagged or ask own question.

Comments