Haskell,List作为函数的输入,如何?

时间:2017-03-29 12:14:32

标签: haskell

我在课程中得到了以下问题;

定义一个函数

var shapes = GetShapes();
List<ShapeHelperClass> helpers = new List<ShapeHelperClass>();
foreach(var shape in shapes)
    helpers.Add(...);

将字符和数字对的列表展平为字符串。例如:

flatten :: [(Char,Int)] -> String

我的问题是,每当我尝试定义此函数时,我都会收到与flatten [('a',5),('b',4),('c',2)] "a5b4c2" flatten [('d',9),('d',3)] "d9d3" 输入相关的类型错误。例如;

[(Char, Int)]

我尝试过多种方式来编写这个定义的方式比我可以计算的更多,所以我没有任何特定的代码可以显示,或者任何特定的错误(我不断得到不同的...很多)。到目前为止我只有;

Couldn't match type '(Char, Int)' with '[Char]'
Expected type: [[Char]]
Actual type: [(Char, Int)]

我认为我的下一行应该是这样的;

flatten :: [(Char, Int)] -> String
flatten [] = []

但我不知道应该用什么来代替这些问号,Google搜索/课堂笔记不提供任何示例。 任何想法?

5 个答案:

答案 0 :(得分:4)

很明显,如果列表为空,则其格式为((ca,cb):cs)caChar,{{1 } cbInt列表的其余部分cs

在这种情况下,我们可以使用show :: Show a => a -> String为该序列构建一个字符串[(Char,Int)],我们将整数转换为ca:(show cb)对应的整数。接下来,我们将列表其余部分的扁平化连接到该字符串,所以:

String

或完整:

flatten ((ca,cb):cs) = ca:(show cb ++ flatten cs)

答案 1 :(得分:3)

首先,我们尝试从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

site.com/file.php?param1=value1&param2=value2

答案 2 :(得分:2)

让我们考虑flatten中的内容以及它的内容。 flatten,列出一对类型为(Char, Int)的对,并生成[Char];它从现有列表中生成一个列表。这会响铃吗?

flatten xs = [ c | (char, int) <- xs, c <-[char] ++ show int]

我们可以按顺序解构给定列表中的每一对;对于每一对,我们将每个组件转换为一个字符串,以便我们可以连接它们。现在我们每个对都有一个字符串,我们只需要取出每个字符来产生最终的字符串。

答案 3 :(得分:1)

您也可以使用foldl使您的意图非常明确:

a=[('a',5),('b',4),('c',2)]
f b (x,y)=b++[x]++(show y)   
result=foldl f "" a

或者你可以把它变成一个单行:

解决方案1:

foldl (\b (x,y)->b++[x]++(show y)) "" a

解决方案2:

concat $ map (\(x,y)->[x]++show y) a

解决方案3 :(与解决方案1相比效率更高)

foldr (\(x,y) b->b++[x]++(show y)) "" a

答案 4 :(得分:1)

flatten = mconcat. map (\(c,i) -> [c] ++ show i)