在我的课程作业中,有人给了我以下问题;
定义函数
flatten :: [(Char,Int)] -> String
它将一对字符和数字的列表扁平化为字符串。例如:
flatten [('a',5),('b',4),('c',2)]
"a5b4c2"
flatten [('d',9),('d',3)]
"d9d3"
我的问题是,每当我试图定义这个函数时,我都会得到一个与[(Char, Int)]
输入相关的类型错误。例如;
无法匹配类型'(Char,Int)‘与'Char’预期类型:[Char]实际类型:(Char,Int)
我尝试了更多的方法来编写这个定义,这比我能计算的更多,所以我没有任何特定的代码可以显示,也没有任何特定的错误(我一直得到不同的ones...so很多)。到目前为止我所拥有的只是;
flatten :: [(Char, Int)] -> String
flatten [] = []
我想我的下一行应该是这样的;
flatten ???? = concat (????)
但我不知道该用什么来代替这些问号,谷歌搜索/课堂笔记也没有给出任何例子。有什么想法吗?
发布于 2017-03-29 12:19:18
很明显,在这种情况下,列表是而不是空的,它是表单((ca,cb):cs)
和ca
Char
,cb
Int
和cs
是列表[(Char,Int)]
的其余部分。
在这种情况下,我们可以简单地为序列ca:(show cb)
用show :: Show a => a -> String
构造一个字符串,我们将一个整数转换为对应的String
。接下来,我们将列表的其余部分与该字符串连接起来,如下所示:
flatten ((ca,cb):cs) = ca:(show cb ++ flatten cs)
或全部:
flatten :: [(Char, Int)] -> String
flatten [] = []
flatten ((ca,cb):cs) = ca:(show cb ++ flatten cs)
发布于 2017-03-29 13:50:56
首先,我们尝试从一个String
创建一个(Char, Int)
。如果我们能做到这一点,我们几乎已经做到了,因为我们可以为所有的(Char, Int)
这样做。所以让我们转换一个单一的(Char, Int)
flattenSingle :: (Char, Int) -> String
flattenSingle (c, i) = c : show i
现在,我们需要对所有条目这样做:
flattenAll :: [(Char, Int)] -> [String]
flattenAll xs = map flattenSingle xs
最后,但同样重要的是,我们需要将concat
[String]
(即[[Char]]
)转换为String
(即[Char]
):
flatten :: [(Char, Int)] -> String
flatten xs = concat (flattenAll xs)
我们就完蛋了。我们怎么做到的?好吧,我们从一个简单得多的问题开始,即如何从一个String
中获得一个(Char, Int)
,并使用它来获得我们的结果。
下面是一个函数中的所有内容:
flatten = concat . map flattenSingle
where
flattenSingle (c, i) = c : show i
因为经常使用concat . map f
,所以有一个叫做concatMap
的函数
flatten :: [(Char, Int)] -> String
flatten = concatMap flattenSingle
where
flattenSingle (c, i) = c : show i
发布于 2017-03-29 15:32:58
让我们考虑一下flatten
中的内容以及它产生的结果。flatten
,获取一个类型对的列表:(Char, Int)
并生成一个[Char]
;它从现有的列表中生成一个列表。这听起来有门铃吗?
flatten xs = [ c | (char, int) <- xs, c <-[char] ++ show int]
我们可以顺序地解构给定列表中的每一对;对于每一对,我们将每个组件转换为一个字符串,以便将它们连接起来。现在我们对每对都有一个字符串,我们只需要把每个字符取出来,生成最后的字符串。
https://stackoverflow.com/questions/43093230
复制相似问题