问题听起来是这样的:编写一个程序,读取数字 n,然后读取 n 个人,对于每个人,读取他们的姓名和年龄,然后返回最年长的人/人。
输入示例:
3
Ion Ionel Ionescu
70
Gica Petrescu
99
Mustafa ben Muhamad
7
Run Code Online (Sandbox Code Playgroud)
输出示例
Oldest is Gica Petrescu (99 years).
Run Code Online (Sandbox Code Playgroud)
到目前为止我的代码:
readPers :: IO(String, Int)
readPers = do
name <- getLine
age <- readLn :: IO Int
return (name, age)
readPerss :: (Ord t, Num t) => t -> [IO (String, Int)]
readPerss n
| n > 0 = readPers : readPerss(n-1)
| otherwise = []
pFunc = do
print "Numer of persons:"
n <- readLn :: IO Int
let persons = readPerss n
return persons
Run Code Online (Sandbox Code Playgroud)
我首先阅读 n,然后尝试使用 readPers 和 readPerss 制作一个人员列表,但我陷入困境,我不知道如何从那时起解决它,我猜到目前为止我的实现不太正确。
我该如何解决这个问题?
你们非常接近!您正在做的readPerss :: (Ord t, Num t) => t -> [IO (String, Int)]是返回一个操作列表IO;每个动作执行时都会返回一对Stringand 。Int目前,pFunc您仅构建此操作列表,将其存储在变量中let,并从 ; 返回它pFunc;您永远不会使用 \xe2\x80\x9cbind\xe2\x80\x9d 语句执行它们<-。
有一些简单的方法可以做你想做的事。执行您想要的操作的代码的最小更改是 add sequence,它采用一个操作容器并生成一个返回容器的操作:
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)\nRun Code Online (Sandbox Code Playgroud)\n\n这t是[]、m是IO、a是(String, Int):
sequence :: [IO (String, Int)] -> IO [(String, Int)]\nRun Code Online (Sandbox Code Playgroud)\n\n另一种方法是重写,readPerss以便直接执行操作,将(String, Int) 结果累积在列表中,而不是累积IO 操作:
readPerss :: (Ord t, Num t) => t -> IO [(String, Int)]\n-- Change [IO \xe2\x80\xa6] to IO [\xe2\x80\xa6]: ~~~~~~~~~~~~~~~~~~\n\nreadPerss n\n | n > 0 = do\n pers <- readPers\n perss <- readPerss (n - 1)\n return (pers : perss)\n | otherwise = return []\nRun Code Online (Sandbox Code Playgroud)\n\n我知道如果这是作业或练习,您可能不应该使用库函数,但在典型的代码中 \xe2\x80\x9creat 重复x操作n次数并累积结果\xe2\x80\x9d 通常表示为replicateM n x:
replicateM :: Applicative m => Int -> m a -> m [a]\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
334 次 |
| 最近记录: |