这是https://haskell.mooc.fi/培训的练习
-- Ex 5: define the IO operation readUntil f, which reads lines from
-- the user and returns them as a list. Reading is stopped when f
-- returns True for a line. (The value for which f returns True is not
-- returned.)
--
-- Example in GHCi:
-- *Set11> readUntil (=="STOP")
-- bananas
-- garlic
-- pakchoi
-- STOP
-- ["bananas","garlic","pakchoi"]
readUntil :: (String -> Bool) -> IO [String]
readUntil f = todo你能用do符号给我一个提示/解决方案吗?我是以do表示法开始的,“条件逻辑”和循环对我来说现在太复杂了。
非常感谢
发布于 2021-12-25 16:15:49
通过只使用do-表示法和条件语句,我找到了以下解决方案:
readUntil :: (String -> Bool) -> IO [String]
readUntil f = do x <- getLine;
if f x then (return []) else (do xs <- readUntil f
return (x : xs))该函数首先从序言中用getLine读取一行,然后检查(f x)是否为真。然后,它只返回空列表。我们不能只编写... if f x then [] ...,因为[]没有IO [String]类型,而只有[String]。为了使[]成为IO [String]类型,我们可以使用函数return或pure,但是对于do-表示法,我使用return函数,因为它包含在Monad类型中。如果f x等于False,那么我们就使用第二个do-块递归地一次又一次地调用函数,直到得到输入( f x == True ),从而返回空列表。do-表示法是必要的,因为xs必须具有[String]类型,但是readUntil具有IO [String]类型。我们不能使用: (“can”)操作符和IO String类型的对象,因此不能生成我们想要的列表。然后我们将x添加到所有其他输入的列表xs中,并返回它。
有关函数readUntil的更通用版本,它能够处理任何单一版本,而不仅仅是IO Monad,请参见Will Ness的评论。
https://stackoverflow.com/questions/70480804
复制相似问题