寻找两个列表元素之间所有映射的Haskell函数[封闭式] 。

问题描述 投票:-1回答:1

我正在努力编写一个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")],
]
haskell functional-programming combinatorics
1个回答
0
投票

由于这显然是作业,而你又没有做尝试,我不会破坏整个解决方案,但这里有一些提示让你开始。

首先,创建一个帮助函数,类型为 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 已经有这方面的功能)。)

© www.soinside.com 2019 - 2024. All rights reserved.