简体   繁体   English

haskell - 无法将类型“(Char, Int)”与“[Char]”错误匹配

[英]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:但是现在类型仍然不匹配: xChar ,而不是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM