我正在努力编写一个Haskell函数,给定两个列表(A和B),返回一个所有映射的列表。A-> B A --> B 其中,一个单一的映射被表示为一个对的列表。函数头将是。
findAllMappings :: [a] -> [b] -> [[(a, b)]]
例如,在对下面的两个列表运行函数后,
findAllMappings [1, 2] ["A", "B"]
我希望得到这样的输出:
[
[(1, "A"), (2, "A")],
[(1, "B"), (2, "B")],
[(1, "A"), (2, "B")],
[(1, "B"), (2, "A")],
]
由于这显然是作业,而你又没有做尝试,我不会破坏整个解决方案,但这里有一些提示让你开始。
首先,创建一个帮助函数,类型为 a -> [b] -> [(a, b)]
. 作为不破坏整个解决方案的一部分,我不会告诉你这个函数应该做什么,但是在它的类型和我下面如何使用它之间,你应该能够找出它。
其次,给了那个助手,对于已知的列表长度,你如何写你的函数是很琐碎的。这里是针对长度0-3的。
findAllMappings [] bs = [[]]
findAllMappings [a0] bs = [[ab0] | ab0 <- helper a0 bs]
findAllMappings [a0, a1] bs = [[ab0, ab1] | ab0 <- helper a0 bs, ab1 <- helper a1 bs]
findAllMappings [a0, a1, a2] bs = [[ab0, ab1, ab2] | ab0 <- helper a0 bs, ab1 <- helper a1 bs, ab2 <- helper a2 bs]
但很明显你不能只为你的最终答案这样做, 因为你需要处理任意长度的列表, 而你不能为每个长度都写一个案例。所以研究一下这是在做什么,然后想一个可以使用递归函数的方法来做。
作为一个替代的方法,想出一个这样的函数(提示。base
已经有了,所以你不需要写它)。)
f 0 ["A", "B"] = [[]]
f 1 ["A", "B"] = [["A"], ["B"]]
f 2 ["A", "B"] = [["A", "A"], ["A", "B"], ["B", "A"], ["B", "B"]]
然后想办法把第一个列表中的元素附加到这个函数中去。findAllMappings
到它的相应结果(提示。base
已经有这方面的功能)。)