Haskell:有条件地中断循环

2023-12-26

我想在这样的情况下打破循环:

import Data.Maybe (fromJust, isJust, Maybe(Just))

tryCombination :: Int -> Int -> Maybe String
tryCombination x y 
               | x * y == 20 = Just "Okay"
               | otherwise = Nothing

result :: [String]
result = map (fromJust) $ 
    filter (isJust) [tryCombination x y | x <- [1..5], y <- [1..5]]

main = putStrLn $ unlines $result

想象一下,“tryCombination”要复杂得多,就像这个例子一样。而且它会消耗大量的 cpu 功率。而且它不是对 25 种可能性的评估,而是对 26^3 种可能性的评估。

因此,当“tryCombination”找到给定组合的解决方案时,它返回 Just,否则返回 Nothing。如何在第一个找到的解决方案上立即打破循环?


简单的解决方案:find and join

看起来您正在寻找Data.List.find http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-List.html#v:find. find具有类型签名

find :: (a -> Bool) -> [a] -> Maybe a

所以你会做类似的事情

result :: Maybe (Maybe String)
result = find isJust [tryCombination x y | x <- [1..5], y <- [1..5]]

或者,如果您不想要Maybe (Maybe String)(为什么要这样做?),你可以将它们折叠在一起Control.Monad.join http://hackage.haskell.org/package/base-4.8.0.0/docs/Control-Monad.html#v:join,其中有签名

join :: Maybe (Maybe a) -> Maybe a

这样你就有了

result :: Maybe String
result = join $ find isJust [tryCombination x y | x <- [1..5], y <- [1..5]]

更高级的解决方案:asum

如果您想要稍微高级的解决方案,您可以使用Data.Foldable.asum https://hackage.haskell.org/package/base-4.7.0.2/docs/Data-Foldable.html,其中有签名

asum :: [Maybe a] -> Maybe a

它的作用是选择第一个Just从许多列表中获取价值。它通过使用Alternative的实例Maybe. The Alternative的实例Maybe工作原理如下:(导入Control.Applicative访问<|>操作员)

λ> Nothing <|> Nothing
Nothing
λ> Nothing <|> Just "world"
Just "world"
λ> Just "hello" <|> Just "world"
Just "hello"

换句话说,它选择第一个Just两种选择的价值。想象一下放<|>在列表的每个元素之间,这样

[Nothing, Nothing, Just "okay", Nothing, Nothing, Nothing, Just "okay"]

被转向

Nothing <|> Nothing <|> Just "okay" <|> Nothing <|> Nothing <|> Nothing <|> Just "okay"

这正是asum功能确实如此!自从<|>是短路的,它只会评估第一个Just价值。有了这个,你的功能就会很简单

result :: Maybe String
result = asum [tryCombination x y | x <- [1..5], y <- [1..5]]

您为什么需要这种更先进的解决方案?它不仅更短,而且更短。一旦你知道了这个习语(即当你熟悉Alternative and asum)只需阅读代码的前几个字符,就可以更清楚该函数的作用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell:有条件地中断循环 的相关文章

随机推荐

  • 如何解压和打包pkg文件?

    我有一个由 Install Maker for Mac 创建的 pkg 文件 我想替换 pkg 中的一个文件 但我必须在Linux系统下执行此操作 因为这是下载过程的一部分 当用户开始下载文件时 服务器必须替换 pkg 中的一个文件 我有一
  • 编译 gtkmm 时出现问题

    操作系统 Fedora 14 编译器 g GCC 4 5 1 20100924 红帽 4 5 1 4 我通过 yum 从存储库安装了 gtkmm24 devel 为了确保安装按计划进行 我决定尝试页面上的示例之一 include
  • Oracle 中的动态表分区

    我正在为我的应用程序构建一个数据库存储 该存储由一个具有巨大数据量 数亿条记录 的表组成 我计划在日期字段上建立索引 因为我将不时地对给定时间段内的所有记录进行批量恢复 例如 检索第二天的所有记录 午夜 由于记录数量巨大并且性能是该系统中的
  • 递归地 (?) 将 LINQ 谓词组合成单个谓词

    编辑 我问错了问题 real我遇到的问题已经结束将 LINQ to SQL 谓词组合成单个谓词 https stackoverflow com questions 3782940 compose linq to sql predicates
  • 在 OS X 上以 32 位模式使用 virtualenv 运行非系统 Python

    简短的问题使用 virtualenv virtualenvwrapper 是否可以添加前缀python调用链接到特定的虚拟环境 背景我想使用多个虚拟环境已安装酿造 https github com mxcl homebrewPython 2
  • 如何从 Kotlin DSL build.gradle 中的所有依赖项中排除库?

    我开始迁移build gradle 时髦 到build gradle kts Kotlin DSL 事情是这样的com google common util concurrent ListenableFuture from com goog
  • Netbeans:自动格式 - 防止变量赋值时出现空格格式

    我更喜欢这样的格式化作业 foo bar long foo bar 而不是这个 foo bar long foo bar 然而 Netbeans 在使用自动格式时使用后者 有人知道如何解决这个问题吗 这个问题已经发布三年了 但我认为它非常有
  • 电子邮件主题分隔符间距中的重音单词 - 如何阻止这种情况?

    我们有一个自定义的 php 电子邮件营销应用程序 还有一个有趣的问题 如果邮件的主题行包含带有重音符号的单词 则会 吞掉 该单词与下一个单词之间的空格 示例 短语 安赫尔 里奥斯 埃斯库查 索普伦德 显示 至少通过 gmail 和 Lotu
  • 数组和右值(作为参数)

    我想知道是否有任何方法可以区分以下代码中显示的函数调用 以数组作为参数 include
  • Python:遍历列表

    我有一个智力挑战谜题 我想用 python 来解决 他们给出了 4 个数字 25 28 38 35 他们希望我们将这些数字放在 一种可能的解决方案是 25 38 35 28 我尝试过 从数字中列出一个列表 用一些循环和 if 来迭代它们 l
  • 无法从我的学校网站获取我的日程安排数据。使用 cURL 登录不起作用

    Edit 为什么要负一呢 我想做的是 我正在尝试使用 cURL 登录我的学校网站并获取时间表以将其用于我的 AI 因此 我需要使用我的通行证和号码登录 但学校网站上的表格还需要一个隐藏的 令牌
  • 将多个 .sql 表转储文件合并到单个文件中

    假设我有数据库A和表b 给定多个 sql 文件 b1 b2 bn 其中每个文件对应于 b 的互斥表转储 我如何将所有文件 b1 b2 bn 合并到单个 sql 表文件中 或者我如何将各个文件的导入合并到一个表中 没有特殊的工具可以做到这一点
  • 循环遍历所有文件夹及其所有子文件夹VBA

    我知道这个问题之前被问过很多次 我已经检查了之前的建议 但我无法让我的代码运行 所以 我有一个名为 Report 的文件夹 其中也包含多个文件夹 这些文件夹包含 xlsx 和 zip 文件 每个文件还包含一个名为 2016 的文件夹 其下有
  • /www 之外的指定虚拟主机上的 Wampserver 403

    当我尝试在 c wamp www 目录之外创建虚拟主机时 Wampserver 告诉我访问被拒绝 我可以在该目录中制作一个罚款 即使对文件夹建立符号链接也可以 但我宁愿不必使用符号链接 为什么不起作用 这是我在 httpd conf 末尾使
  • Django 上多租户应用程序的最佳架构

    我一直在思考创建基于多租户应用程序的正确 最佳方法 关于姜戈 一些解释 应用程序可由多个租户 tenant1 tenant2 使用 所有租户个人数据都必须受到保护 防止其他租户 及其用户 访问 租户可以选择为应用程序对象创建额外的自定义字段
  • 计算数组数组中的项目数?

    如果我有一个声明为的对象 let compoundArray Array
  • 在 Visual Studio 中对文件进行分组

    我正在考虑在 Visual Studio 中整理我的项目布局 我想知道是否有任何 hack 插件或技巧可以将 xml 文件与 cs 文件关联起来同名所以它们出现在我的解决方案导航器 资源管理器中 类似于代码隐藏文件与其 aspx 关联的方式
  • 从 Mac 上的 SWT 应用程序打开 LWJGL 窗口

    我有一个 SWT 应用程序 可以在按下按钮后打开 OpenGL 窗口 使用 LWJGL 库 它应该关闭它的主 SWT 窗口并打开一个带有 OpenGL 上下文的新窗口 在 Windows 上运行良好 在 Mac 上 我收到此错误 2010
  • Azure 托管和 MVC5 报告

    我正在使用 Visual Studio 2013 开发托管在 Azure 上的 MVC5 EF6 Web 应用程序 我刚刚完成需要创建报告的开发部分 我试图使用 Microsoft ReportViewer 来实现此目的 尽管它在本地工作得
  • Haskell:有条件地中断循环

    我想在这样的情况下打破循环 import Data Maybe fromJust isJust Maybe Just tryCombination Int gt Int gt Maybe String tryCombination x y