我正在尝试阅读用户输入的信息并将其解析为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单子。使用它,我得到了以下代码:
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
函数时,出现了错误消息。
如何解决这个问题?编写此代码时,我使用了有关Monad变换器的wikibook。没有(Data.Functor.Classes.Show1 IO)的实例 来自使用`print'的互动GHCi命令的语句 : print it
编辑:当我尝试使用
runMaybeT
运行它时,它被执行了,但它并不安全。例如,输入无意义的年龄仍然会导致输出,如下所示:
Person {name: 85, age: *** Exception: Prelude.read: no parse.
runMaybeT
吗? - pdexterPerson
的定义。 - ErikRreadMaybe
。 - pdexterdo
块中的每个操作提取出来。您从未在实际的Maybe
单子中执行任何操作。 - pdexterMaybe
单子内读取这些值呢?这样是不行的:gender <- maybeRead genderStr::Gender
,因为我不知道如何正确地转换读取到的值。 - zimmerrol