首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Haskell练习Mooc FI Do表示法

Haskell练习Mooc FI Do表示法
EN

Stack Overflow用户
提问于 2021-12-25 14:56:30
回答 1查看 76关注 0票数 0

这是https://haskell.mooc.fi/培训的练习

代码语言:javascript
运行
复制
-- 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表示法开始的,“条件逻辑”和循环对我来说现在太复杂了。

非常感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-25 16:15:49

通过只使用do-表示法和条件语句,我找到了以下解决方案:

代码语言:javascript
运行
复制
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]类型。我们不能使用: (“can”)操作符和IO String类型的对象,因此不能生成我们想要的列表。然后我们将x添加到所有其他输入的列表xs中,并返回它。

有关函数readUntil的更通用版本,它能够处理任何单一版本,而不仅仅是IO Monad,请参见Will Ness的评论。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70480804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档