我在做Problem 15。哪个州:
(**) Replicate the elements of a list a given number of times.
Example:
* (repli '(a b c) 3)
(A A A B B B C C C)
Example in Haskell:
> repli "abc" 3
"aaabbbccc"
我的计划是做这样的事情:
repli :: [a] -> Integer -> [a]
repli [] y = []
repli (x:xs) y | appendNo x y == [] = repli(xs) y
| otherwise = appendNo x y : (x:xs)
where
appendNo :: a -> Integer -> [a]
appendNo a 0 = []
appendNo a y = a:appendNo a (y-1)
我将创建一个名为appendNo的函数,该函数返回1个元素的列表y次,然后将其追加到原始列表中。然后取出列表的主体并重复此过程,直到没有剩余的主体元素。但是,我收到错误:
H15.hs:6:30:
Couldn't match type `a' with `[a]'
`a' is a rigid type variable bound by
the type signature for repli :: [a] -> Integer -> [a] at H15.hs:3:1
In the return type of a call of `appendNo'
In the first argument of `(:)', namely `appendNo x y'
In the expression: appendNo x y : (x : xs)
Failed, modules loaded: none.
6:30
位于此行中p
的{{1}}位置:
appendNo
好的,谢谢dave4420我能做到这一点:
| otherwise = appendNo x y : (x:xs)
答案 0 :(得分:4)
| otherwise = appendNo x y : (x:xs)
此行中存在类型错误。所以问问自己:
appendNo x y
的类型是什么?(x:xs)
的类型是什么?(:)
的类型是什么?然后你应该能够看出他们为什么不匹配。
如果你仍然看不出他们为什么不匹配,那就问问自己
x
的类型是什么?xs
的类型是什么?(:)
的类型是什么?请记住,这次做类型匹配。
答案 1 :(得分:1)
问题解决了,让我给你一个提示:你应该尝试在转换中思考,而不是在“循环”中思考。从一些具体的值开始,如n = 3和list =“ABCD”。然后你应该按照“我需要每个元素三次”的思路。已有一个执行复制的功能,令人惊讶地称为replicate
。因此,句子可以翻译为map (replicate 3) "ABCD"
,这会给你["AAA","BBB","CCC","DDD"]
。这几乎是你想要的,你只需要concat
元素。这给出了:
repli list n = concat (map (replicate n) list)
由于此操作非常常见,因此concatMap
和concat
组合map
,以及运算符(>>=)
执行相同操作,只需使用翻转参数。所以一个非常简短的解决方案是:
repli list n = list >>= replicate n
这也可以翻译成记号或列表理解:
repli list n = do
x <- list
y <- replicate n x
return y
repli list n = [y | x <- list, y <- replicate n x]