Haskell Exercise Mooc FI Do notation



这是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表示法的开始;条件逻辑";以及循环目前对我来说太复杂了。

非常感谢

只使用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],我们可以使用函数returnpure,但使用do表示法时,我使用return函数,因为它包含在Monad类型类中。如果f x等于False,那么我们使用第二个do块一次又一次地递归调用该函数,直到我们得到f x == True的输入,并因此返回空列表。do表示法是必要的,因为xs的类型必须是[String],而readUntil的类型是IO [String]。我们不能将:("cons"(运算符与类型为IO String的对象一起使用,因此不能生成我们想要的列表。然后,我们将x添加到所有其他输入的列表xs中,并返回它

关于函数readUntil的更通用版本,它可以与任何monad(而不仅仅是IOmonad(一起工作,请参阅Will Ness 的评论

最新更新