Haskell错误与类似复制的函数

时间:2014-02-18 12:02:18

标签: haskell replicate

我想写一个像这样的类似复制的函数:

  

repli“the”3 =“ttthhheee”and   repli“jason”4 =“jjjjaaaassssoooonnnn”

这是我写的代码:

myrepli []  n = []
myrepli [x] 0 = []
myrepli [x] n = (x:(myrepli [x] (n-1)))


repli [] n = []
repli (x:xs) n = (myrepli x n) ++ (repli xs n)

我得到的错误是:

Couldn't match expected type `[a]' against inferred type `Char'
     Expected type: [[a]]
     Inferred type: [Char]
   In the first argument of `repli', namely `"jason"'
   In the expression: repli "jason" 3

我该如何解决这个问题?感谢。

2 个答案:

答案 0 :(得分:8)

对于类型问题,这里有一个帮助我很大的技巧。每当我对这样的消息感到困惑时,我会做以下事情:

  • 如果相关功能上有类型签名,请将其删除并查看是否有任何更改。如果它编译,请询问ghci类型是什么(使用:t)。如果它没有编译,至少错误消息可能有足够的差异给你另一条线索。
  • 如果没有类型签名,请添加一个。即使它没有编译,错误消息也可能会给你另一条线索。
  • 如果这没有用,那么暂时在函数中的每个表达式上添加类型声明。 (通常你需要分解一些表达式才能看到真正发生的事情。你可能还需要暂时启用ScopedTypeVariables编译指示。)再次编译并检查错误消息。

最后一个是更多的工作,但我从这个练习中学到了很多东西。它通常会指出我认为类型与GHC认为的类型之间存在不匹配的确切位置。

让我们首先在代码中添加类型签名:

myrepli :: [a] -> Int -> [a]
myrepli []  n = []
myrepli [x] 0 = []
myrepli [x] n = (x:(myrepli [x] (n-1)))


repli :: [a] -> Int -> [a]
repli [] n = []
repli (x:xs) n = (myrepli x n) ++ (repli xs n) -- triggers a compiler error

啊,现在我们收到编译错误:

amy.hs:9:27:
    Couldn't match expected type `a' with actual type `[a]'
      `a' is a rigid type variable bound by
          the type signature for repli :: [a] -> Int -> [a] at amy.hs:7:10
    In the first argument of `myrepli', namely `x'
    In the first argument of `(++)', namely `(myrepli x n)'
    In the expression: (myrepli x n) ++ (repli xs n)

问题在于对myrepli x n的调用。函数myrepli需要一个列表/字符串,但是你传递一个字符。将最后一行更改为:

repli (x:xs) n = (myrepli [x] n) ++ (repli xs n)

此时您将在代码中发现其他错误。但是,不要修复你的代码,让我告诉你另一种方法:

repl (x:xs) n = (myReplicate x n) ++ (repl xs n)
repl [] _ = []

-- You could use the library function "replicate" here, but as a
-- learning exercise, we'll write our own.
myReplicate a n = take n (repeat a)

答案 1 :(得分:3)

myrepli期待列表和整数。但是,repli的定义将其称为x,这是一个项目,而不是项目的列表

我想你要么要更改myrepli以将单个项目作为参数,要更改repli以通过{ {1}}而非[x]。 (我建议前者而不是后者。)