迭代 Data.Set 直到成功

2024-01-27

假设我有一个代表某些可能失败的计算的函数

f :: a -> Maybe b

如果我有一个清单l,我可以找到列表中的第一个(从左到右扫描时)项目f成功使用findList f l, where findList是下面的函数

findList :: (a -> Maybe b) -> [a] -> Maybe b
findList f [] = Nothing
findList f (x : xs) = case f x of
  Nothing -> findList f xs
  Just y -> Just y

(或使用,例如firstJust https://hackage.haskell.org/package/extra-1.7.9/docs/Data-List-Extra.html#v:firstJust来自extra包裹)。

问题。

如果我想对一个人做同样的事情我该怎么办Set https://hackage.haskell.org/package/containers-0.6.4.1/docs/Data-Set.html#t:Set from containers?

也就是说,我想要一个带有签名的函数

findSet :: (a -> Maybe b) -> Set a -> Maybe b

这相当于

findSet f s = findList f (Set.toList s)

上面的行作为一个实现。但是,我不想创建中间列表Set.toList s(即使使用惰性求值,仍然存在一些不必要的开销,对吧?)。

一旦找到成功的项目,我也不想迭代整个集合,如以下实现所示:

findSet f s = foldl g Nothing s
  where
    g Nothing x = f x
    g (Just y) _ = Just y

那么是否有一种好方法可以“从左到右”遍历集合,应用可能对每个成员失败的计算,并在第一个成功结果处停止?


我想分享一个 IRC 上的人曾经向我展示的一个小技巧:成功时提前退出只是错误时提前退出的另一种解释。考虑到这一点,请考虑使用Either b ()代替Maybe b; then

findOne :: (a -> Either b ()) -> Set a -> Either b ()
findOne = traverse_

甚至不值得命名。如果你必须有Maybe,你可以简单地用明显的同构来包装它。

findOneMaybe :: (a -> Maybe b) -> Set a -> Maybe b
findOneMaybe f = to . traverse_ (from . f) where
    from = maybe (Right ()) Left
    to = either Just (const Nothing)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迭代 Data.Set 直到成功 的相关文章

  • 由于标志字节串 -lt-0_10_4,无法使用 Stack 构建 hello world 程序

    通过生成一个裸露的 hello world 项目 stack new myproject simple 每当我跑步时stack setup stack init or stack build我总是出现以下错误 Downloading lts
  • Haskell:Where 与 Let

    我是 Haskell 的新手 我很困惑Where vs Let 它们似乎都提供了相似的目的 我读过一些比较Where vs Let但我很难辨别何时使用它们 有人可以提供一些背景信息或者一些示例来说明何时使用其中一种而不是另一种吗 哪里与让
  • 如何使用 swift flatMap 从数组中过滤掉选项

    我对 flatMap 有点困惑 添加到 Swift 1 2 假设我有一些可选类型的数组 例如 let possibles Int nil 1 2 3 nil nil 4 5 在 Swift 1 1 中 我会做一个过滤器 然后是一个像这样的地
  • 通过 Emacs 评估 ghci 或 Hugs 中的缓冲区

    在 Emacs 中使用 sml mode 我已经能够使用以下命令将缓冲区内容直接发送到较差的 SML 进程C c C b 现在我只想用 Haskell 做同样的事情 Haskell 模式似乎不支持这一点 所以我想知道 使用 Emacs 和
  • 整数转浮点数

    这段代码的工作原理 posToXY Float gt Float gt Integer posToXY a b do let y a b round y 但这不起作用 posToXY Integer gt Integer gt Intege
  • 使用 nix 在 Mac OS X 上由于“架构 x86_64 的未定义符号”而导致“堆栈构建”失败

    首先是错误消息 stack build Linking Users yuzhao stack setup exe cache x86 64 osx tmp Cabal simple mPHDZzAJ 2 2 0 1 ghc 8 4 4 cl
  • 为什么 Haskell 中有协函子和逆变函子的区别,而范畴论却没有区别?

    这个答案是从范畴论的角度来看的 https math stackexchange com a 661989 72174包括以下语句 事实是 协函子和逆变函子之间没有真正的区别 因为每个函子只是一个协变函子 More in details a
  • 导入 Haskell 模块

    我是哈斯克尔的新手 为什么当我尝试使用时Days from Data Time我收到此错误 Could not find module Data Time It is a member of the hidden package time
  • ErrorT 已弃用,但 exceptT 不适合

    我有一个一元计算 在某些时候 由于单子模式匹配 它开始需要 MonadFail 约束 我的简单解决方法是使用以下命令运行它 fmap either error id runErrorT 然而哎呀 Deprecated Use Control
  • 如何让 Show 显示函数名称?

    作为一个让我熟悉 Haskell 的简单练习 在 Youtube 上闲逛并偶然进入美国倒计时游戏节目之后 我想为数字游戏制作一个求解器 你得到 6 个数字 需要将它们与 为了得到给定的结果 到目前为止我所得到的是非常脑死亡的 let ope
  • 在 Haskell 中增长数组

    我想在 Haskell 中实现以下 命令式 算法 给定一个序列对 e0 s0 e1 s1 e2 s2 en sn 其中 e 和 s 部分不一定是自然数不同的是 在每个时间步都会随机选择该序列的一个元素 例如 ei si 并根据 ei si
  • 我应该在 Turtle 或 Foldl 包中使用折叠吗?

    我在使用 Turtle 时遇到了一些困难 直到盯着难以理解的错误消息几分钟后才意识到我使用了错误的fold功能 https hackage haskell org package turtle 1 5 8 docs Turtle Shell
  • 纯函数怎么能做IO呢?

    我最近了解到莫纳德随机数 http hackage haskell org package MonadRandom 0 1 13 docs Control Monad Random Class html t 3aMonadRandom图书馆
  • 固定大小集以包含给定集的最大数量

    我有大约 1000 组尺寸 1 4 1 3 3 5 6 4 5 6 7 5 25 42 67 100 是否有可能找到包含最大数量的给定集合的大小为 20 的集合 检查每一个100 80 20 集 效率低下 我不太确定这是 NP 完全的 考虑
  • 以下两个 lambda 函数的空间复杂度

    我正在阅读以下内容 https en wikibooks org wiki Haskell Graph reduction https en wikibooks org wiki Haskell Graph reduction 其内容如下
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • Haskell 中列表列表的笛卡尔积

    给定一个长度列表的列表x所有子列表的长度都相同y 输出y x长度列表x包含每个子列表中的一项 例子 x 3 y 2 1 2 3 4 5 6 Output 2 3 8不同的输出 1 3 5 1 4 5 1 3 6 1 4 6 2 3 5 2
  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • 如何正确删除动画集中引用的 Raphael SVG 元素?

    我有一组动画 Raphael SVG 元素 我正在通过用户发起的 ajax 调用添加新元素并删除旧元素 我 set push 新元素 但因为我需要删除的元素通常不是集合中的最后一个元素 所以我使用 element remove 而不是 se
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频

随机推荐