Haskell无法压缩字符串,然后与列表理解结合

时间:2018-08-16 16:11:37

标签: haskell

combineIndex :: String -> String -> [Char]
combineIndex pair1 pair2 = [a ++ b | (a, b) <- zip pair1 pair2]

combineIndex "AB" "CD"应该返回["AC", "BD"],但我一直在输入错误。

2 个答案:

答案 0 :(得分:6)

  

combineIndex "AB" "CD"应该返回["AC", "BD"],但我一直在遇到类型错误。

首先让我们看看您的函数的签名:

combineIndex :: String -> String -> [Char]
combineIndex pair1 pair2 = [a ++ b | (a, b) <- zip pair1 pair2]

作为结果类型,您指定了[Char],因此指定了Char的列表(实际上是String)。但在结果中,您需要一个String列表,因此输出类型应为[String]。因此,让我们首先修复签名:

combineIndex :: String -> String -> [String]
combineIndex pair1 pair2 = [a ++ b | (a, b) <- zip pair1 pair2]

现在,为了创建这样的字符串,我们可能首先分析涉及的变量的类型。 zip :: [a] -> [b] -> [(a, b)],将返回2元组的列表[(Char, Char)]。因此,这意味着列表理解中的ab都是Char。通过构造两个元素String的列表,我们可以将这些字符转换为[a,b]。因此,我们可以使用以下方法修复该功能:

combineIndex :: String -> String -> [String]
combineIndex pair1 pair2 = [ [a, b] | (a, b) <- zip pair1 pair2]

(++) :: [a] -> [a] -> [a]函数在这里不起作用,因为它需要两个列表(元素类型为相同),并将这些列表连接在一起。但是Char不是列表,String是(自type String = [Char]起)。我们可以使用[a] ++ [b]而不是[a, b],但是这样做只会使嘈杂效率更低。

请注意,我们可以泛化该功能以进一步:

combineIndex :: [a] -> [a] -> [[a]]
combineIndex pair1 pair2 = [ [a, b] | (a, b) <- zip pair1 pair2]

因此,现在它将与具有相同对象类型的任何两个列表一起使用。例如,如果我们用数字来称呼它,我们得到:

Prelude> combineIndex [1,4,2,5] [1,3,0,2]
[[1,1],[4,3],[2,0],[5,2]]

答案 1 :(得分:5)

zip返回 Char 值的元组,而不是String值,因此您不能在++上使用ab。您只需要一个普通列表。

combineIndex p1 p2 = [[a,b] | (a, b) <- zip p1 p2]