这可能是最简单的一个:
Prelude> let odometer a = sequence a
Prelude> odometer [["a1","a2","a3"],["b1","b2"],["c1","c2","c3","c4"]]
[["a1","b1","c1"],["a1","b1","c2"],["a1","b1","c3"],["a1","b1","c4"],["a1","b2","c1"],
["a1","b2","c2"],["a1","b2","c3"],["a1","b2","c4"],["a2","b1","c1"],["a2","b1","c2"],
["a2","b1","c3"],["a2","b1","c4"],["a2","b2","c1"],["a2","b2","c2"],["a2","b2","c3"],
["a2","b2","c4"],["a3","b1","c1"],["a3","b1","c2"],["a3","b1","c3"],["a3","b1","c4"],
["a3","b2","c1"],["a3","b2","c2"],["a3","b2","c3"],["a3","b2","c4"]]
Prelude>
sequence
是一个处理 monad 的函数。如果你想使用 Haskell,你需要了解 monad,所以不妨从现在开始。
如果你还没有准备好让强大的 monad 进入你的生活,这里有一个更普通的版本:
Prelude> :{
Prelude| let odometer (xs:yys) = [x:ys | x<-xs, ys<-odometer yys]
Prelude| odometer [] = [[]]
Prelude| :}
Prelude> odometer [["a1","a2","a3"],["b1","b2"],["c1","c2","c3","c4"]]
[["a1","b1","c1"],["a1","b1","c2"],["a1","b1","c3"],["a1","b1","c4"],["a1","b2","c1"],
["a1","b2","c2"],["a1","b2","c3"],["a1","b2","c4"],["a2","b1","c1"],["a2","b1","c2"],
["a2","b1","c3"],["a2","b1","c4"],["a2","b2","c1"],["a2","b2","c2"],["a2","b2","c3"],
["a2","b2","c4"],["a3","b1","c1"],["a3","b1","c2"],["a3","b1","c3"],["a3","b1","c4"],
["a3","b2","c1"],["a3","b2","c2"],["a3","b2","c3"],["a3","b2","c4"]]
Prelude>
它完全按照它在锡上所说的那样做:
- 给定里程表轮的列表
(xs:yys)
- 所有可能读数的列表是x和ys的所有可能组合的列表
= [ x:ys
- 这样
|
- x取自第一个轮子的所有可能位置的列表
x<-xs
- 和
,
- ys取自由其余车轮(即除了第一个车轮之外的所有车轮)构成的里程表的所有可能读数的列表
ys<-odometer yys]
。
- 如果里程表没有轮子
[]
- 只有一种可能的读数,它是空的
= [[]]