H-15遇到麻烦

时间:2012-01-21 19:55:06

标签: haskell

我在做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)

2 个答案:

答案 0 :(得分:4)

       | otherwise = appendNo x y : (x:xs)

此行中存在类型错误。所以问问自己:

  1. appendNo x y的类型是什么?
  2. (x:xs)的类型是什么?
  3. (:)的类型是什么?
  4. 然后你应该能够看出他们为什么不匹配。

    如果你仍然看不出他们为什么不匹配,那就问问自己

    1. x的类型是什么?
    2. xs的类型是什么?
    3. (:)的类型是什么?
    4. 请记住,这次类型匹配。

答案 1 :(得分:1)

问题解决了,让我给你一个提示:你应该尝试在转换中思考,而不是在“循环”中思考。从一些具体的值开始,如n = 3和list =“ABCD”。然后你应该按照“我需要每个元素三次”的思路。已有一个执行复制的功能,令人惊讶地称为replicate。因此,句子可以翻译为map (replicate 3) "ABCD",这会给你["AAA","BBB","CCC","DDD"]。这几乎是你想要的,你只需要concat元素。这给出了:

repli list n = concat (map (replicate n) list)

由于此操作非常常见,因此concatMapconcat组合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]