首先,我想应该修复“无处不在”以获得其名称所期望的行为:
fun everywhere e nil = [[e]]
| everywhere e (y::ys) =
(e::y::ys) :: (map (fn u => y::u) (everywhere e ys));
这个修改后的版本提供了一个列表列表。例如,
- everywhere 4 [1,2,3] ;
val it = [[4,1,2,3],[1,4,2,3],[1,2,4,3],[1,2,3,4]] : int list list
所以,你可能知道 "everywhere e xs" 枚举了所有可能的列表,这些列表是通过将项目 "e" 插入到原始列表 xs 的某处而生成的。
那么,如何枚举插入呢?分为两种情况:
- 在顶部插入:[1,2,3] -> [4, 1,2,3]
- 在第一个和第二个或更晚之间插入:[1, 4 ,2,3], [1,2, 4 ,3],...
案例 1 仅由 (e::y::ys) 实现。
案例2进一步分为两步:
- A) 获得将“e”插入第二个和以下项目的子列表“ys”的所有可能性:[4,2,3],[2,4,3],...李>
- B) 将原始列表的第一项“y”添加到步骤 A 的结果的 EACH 中:
1 :: [4,2,3], 1::[2,4,3], ...
步骤 2A 可以通过使用子列表作为参数调用“everywhere”本身来完成。然后,将项目“y”附加到每个(无处不在)中,您已经完成了步骤 2B。
为此(对项目做同样的事情),您可以使用“地图”。