list
在 Haskell 中,列表类型 []
是一个 Applicative
的实例,这意味着我们可以使用 Applicative
的操作在列表中应用函数。这种特性在需要对所有可能组合进行计算的场景中非常有用。
Applicative 列表的基础
首先,我们了解一下列表在 Applicative
中的作用:
-
pure
函数会将一个值放入一个单元素的列表中。pure 5 :: [Int] -- 结果:[5]
-
<*>
运算符用于将一个包含函数的列表应用到另一个包含值的列表。列表的Applicative
实现会将所有可能的组合进行应用。
例如:
[(+1), (*2)] <*> [1, 2, 3]
-- 结果:[2, 3, 4, 2, 4, 6]
在这个例子中,每个函数都会应用到每个值上,从而得到所有的组合。
例子:生成所有可能的组合
假设我们要生成字母和数字的所有组合,可以这样使用列表的 Applicative
:
letters = ['a', 'b']
numbers = [1, 2]
combinations = (,) <$> letters <*> numbers
-- 结果:[('a',1),('a',2),('b',1),('b',2)]
这里,(,) <$> letters <*> numbers
的含义是,将 letters
和 numbers
中的每个值组合在一起,得到一个包含所有可能组合的列表。
列表 Applicative 的作用
- 生成笛卡尔积:通过
Applicative
可以轻松生成列表的笛卡尔积。 - 组合多个计算:可以组合多个不同的操作,比如对所有组合进行计算,尤其在生成测试数据或枚举所有情况时非常有用。
- 简化代码:避免了手动嵌套多个列表遍历,可以直接用
<*>
实现所有组合。
实际应用
-- 求出 [1,2,3] 中每个元素的平方以及三倍:
results = [(^2), (*3)] <*> [1, 2, 3]
-- 结果:[1,4,9,3,6,9]
以上代码分别对 [1,2,3]
中每个元素应用平方和三倍,直接得到所有可能结果。