list - 在 Haskell 中减少由 Bool 和 Rational 值组成的条目的列表
问题描述
我得到一个列表,其中包含由 Bool 和 Rational 值组成的条目,如下所示:
[(False,1 % 40),(False,9 % 40),(False,1 % 40),(False,9 % 40),
(False,1 % 40),(False,9 % 40),(False,1 % 40),(True,9 % 40)]
我想将共享 Bool 值的条目减少为一个,并将相应的 Rational 值相加。
上述示例的结果应如下所示:
[(False,31 % 40),(True,9 % 40)]
我是 Haskell 的新手,并尝试使用 foldM 完成任务,但我认为这不是正确的方法。
任何帮助深表感谢。
解决方案
您确实可以在fold
这里使用 a 。我将在这里使用一个 2 元组,例如,第一个元素包含False
s 的总和,第二个元素包含 s 的总和True
:
import Control.Arrow(first, second)
import Data.Bool(bool)
dsum :: (Foldable f, Num a) => f (Bool, a) -> (a, a)
dsum = foldr (uncurry ((. (+)) . bool first second)) (0,0)
对于可折叠的(Bool, a)
元组,它将计算一个 2 元组,其中第一个元素包含(False, ...)
元组的总和,第二个元素包含元组的总和(True, ...)
。
这(uncurry ((. (+)) . bool first second))
是一个函数的紧凑表示f
:
f :: Num a => (Bool, a) -> (a, a) -> (a, a)
f (False, d) (a, b) = (d+a, b)
f (True, d) (a, b) = (a, d+b)
例如:
Prelude> d = [(False,1 % 40),(False,9 % 40),(False,1 % 40),(False,9 % 40), (False,1 % 40),(False,9 % 40),(False,1 % 40),(True,9 % 40)]
Prelude> dsum d
(31 % 40,9 % 40)
通过使用 2 元组,我们因此添加了一个“合同”,我们将恰好有两个元素,这通常比总是包含两个项目的列表更可取。
推荐阅读
- dart - Flutter:从另一个 Dart 文件中获取 AlertDialog
- javascript - 在浏览器中检测实时音频输入的音高
- javascript - 使用Javascript从右到左插入排序
- asp.net - 在代码中设置 Bugsnag 配置选项
- python - 如何从 CSV 中正确提取值?- Python
- sql - PostgreSQL中的Alter Table在本地需要很长时间
- android - Room Dao LiveData 作为返回类型导致编译时错误
- java - btoa函数如何在Javascript中使用
- c# - Microsoft.ACE>OLEDB12.0' 提供程序未在本地计算机上注册
- spring - 具有多个数据库操作的 Spring Transactional on 方法