[英]haskell - Couldn't match type ‘(Char, Int)’ with ‘[Char]’ error
I am writing a function to expand a String我正在编写一个函数来扩展字符串
Example:例子:
foo "a4b4"
should give back:应该回馈:
"aaaabbbb"
Here is my code:这是我的代码:
foo :: String -> String
foo (x:xs) = let curent = fooHelp(x, read $ charToString( xs !! 0 ) :: Int)
in x : (curent) ++ foo (tail xs)
fooHelp:帮助:
fooHelp :: String -> Int -> String
fooHelp x n
| n >= 3 = x ++ fooHelp x (n - 1)
| n == 2 = x
| n == 1 = ""
and charToString:和 charToString:
charToString :: Char -> String
charToString c = [c]
it takes x and appends it to the current.它需要 x 并将其附加到当前。 In current fooHelp will give back expanded String
在当前的 fooHelp 中将返回扩展的 String
example : foo "a4b4"
then x = "a"
, xs = "4b4"
, xs !! 0 = '4'
例如:
foo "a4b4"
然后x = "a"
, xs = "4b4"
, xs !! 0 = '4'
xs !! 0 = '4'
read $ charToString( xs !! 0 ) :: Int)
will convert char '4'
to int 4
and pass it to fooHelp alongside with x("a") -> fooHelp(x, 4)
and give back "aaa". xs !! 0 = '4'
read $ charToString( xs !! 0 ) :: Int)
将 char '4'
转换为 int 4
并将其与 x("a") -> fooHelp(x, 4)
一起传递给 fooHelp 并给出回“啊”。 Then x : current
should give back "aaaa"
because x = "a"
and current "aaa"
and then recursive call with ++ foo tail xs
where xs ="b4"
and it should repeat the process.然后
x : current
应该返回"aaaa"
因为x = "a"
和 current "aaa"
然后递归调用++ foo tail xs
where xs ="b4"
它应该重复这个过程。
I am getting the error:我收到错误:
test.hs:173:34: error:
• Couldn't match type ‘(Char, Int)’ with ‘[Char]’
Expected type: String
Actual type: (Char, Int)
• In the first argument of ‘fooHelp’, namely
‘(x, read $ charToString (xs !! 0) :: Int)’
In the expression:
fooHelp (x, read $ charToString (xs !! 0) :: Int)
In an equation for ‘curent’:
curent = fooHelp (x, read $ charToString (xs !! 0) :: Int)
|
173 | foo (x:xs) = let curent = fooHelp(x, read $ charToString( xs !! 0 ) :: Int)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Where did I make mistake?我哪里出错了? I tested function fooHelp and it works fine with such arguments as in foo.
我测试了函数 fooHelp,它可以很好地处理 foo 中的参数。
Testing fooHelp:测试 fooHelp:
xs = "4b4"
test = read $ charToString( xs !!0 ) :: Int
*Main> test
4
The expression fooHelp(x, read $ charToString( xs !! 0 ) :: Int)
tries to pass a single argument — a (Char, Int)
pair — to fooHelp
, which is wrong.表达式
fooHelp(x, read $ charToString( xs !! 0 ) :: Int)
试图将单个参数 — (Char, Int)
对 — 传递给fooHelp
,这是错误的。 Presumably, you want to instead write:据推测,您想改写:
fooHelp (charToString x) (read $ charToString( xs !! 0 ) :: Int)
A classic mistake is to call a function like f (x1, x2)
.一个典型的错误是调用像
f (x1, x2)
这样的函数。 In Haskell functions have one parameter, and often this is not a tuple.在 Haskell 中,函数只有一个参数,通常这不是元组。
Your fooHelper
function has type:您的
fooHelper
函数具有以下类型:
fooHelp :: String -> (Int -> String)
so it is a function that takes a String
, and the returns a function that maps Int
s on String
s.所以它是一个接受
String
的函数,并返回一个将Int
映射到String
的函数。 You thus should call the function like:因此,您应该像这样调用函数:
(fooHelp x) (read $ charToString( xs !! 0 ) :: Int)
or less verbose:或不那么冗长:
(fooHelp x) (read $ charToString( xs !! 0 ) :: Int)
But now the types still not match: x
is a Char
, not a String
, you can wrap it in a list, like:但是现在类型仍然不匹配:
x
是Char
,而不是String
,您可以将其包装在列表中,例如:
fooHelp [x] (read $ charToString( xs !! 0 ) :: Int)
like:喜欢:
foo :: String -> String
foo (x:xs) = let curent = fooHelp [x] (read $ charToString( xs !! 0 ) :: Int)
in x : (curent) ++ foo (tail xs)
But still this function has a problem: we iterate over the string, so eventually we will reach an empty string, and foo
has no case for that.但是这个函数仍然有一个问题:我们遍历字符串,所以最终我们会得到一个空字符串,而
foo
没有这种情况。 We need to return the empty string in that case, like:在这种情况下,我们需要返回空字符串,例如:
foo :: String -> String
foo (x:xs) = let curent = fooHelp [x] (read $ charToString( xs !! 0 ) :: Int)
in x : (curent) ++ foo (tail xs)
foo [] = ""
But it is still not very elegant.但它仍然不是很优雅。 We here perform a lot of unnecessary operations, like wrapping characters to strings, etc.
我们在这里执行了很多不必要的操作,比如将字符包装成字符串等。
We can make use of the replicate :: Int -> a -> [a]
function to repeat a character a given number of times.我们可以使用
replicate :: Int -> a -> [a]
函数来重复一个字符给定的次数。 For example:例如:
Prelude> replicate 3 'a'
"aaa"
Furthermore the digitToInt :: Char -> Int
function can parse a digit character to the corresponding Int
:此外
digitToInt :: Char -> Int
函数可以将数字字符解析为相应的Int
:
Prelude Data.Char> digitToInt '3'
3
So we here can use these two to each time take the first two characters of the string, and use replicate (digitToInt k) x
to generate a string where x
si repeated the requested amount of time, and perform recursion on the rest of the string, like:所以我们这里可以使用这两个来每次取字符串的前两个字符,并使用
replicate (digitToInt k) x
生成一个字符串,其中x
si 重复请求的时间量,并对字符串的其余部分执行递归, 喜欢:
import Data.Char(digitToInt)
foo :: String -> String
foo (x:k:xs) = replicate (digitToInt k) x ++ foo xs
foo _ = ""
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.