我试图读取用户输入的信息并将其解析为 Person
类型,该类型使用 Gender
类型 . 为此,我使用此代码:
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
现在我想让这更安全 - 为了达到这个目的,我尝试使用MaybeT monad . 使用这个,我得到了这个代码:
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"
它由GHCI编译/加载,但当我尝试执行 readPersonMaybeT
函数时,我收到错误消息
使用`print'时没有(Data.Functor.Classes.Show1 IO)的实例在交互式GHCi命令的stmt中:打印它
我该如何解决这个问题?编写这段代码,我使用了关于Monad变形金刚的wikibook .
编辑:当我尝试'run'它与 runMaybeT
它被执行,但它根本不是故障保护 . 例如,为年龄输入废话仍会产生类似的输出
人{姓名:85,年龄:***例外:Prelude.read:没有解析 .
1 回答
如果您在询问所有输入后才进行验证,我只需使用IO monad并返回Maybe:
注意我们如何在
return
语句中使用Maybe monad .如果您想在输入无效值时退出询问输入,我会使用MaybeT -
如果用户输入无效年龄,则不会要求他们提供性别 .