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

标签 haskell syntax syntax-error type-mismatch function-call

我正在编写扩展字符串的函数

例:

foo "a4b4"

应该回馈:
"aaaabbbb"

这是我的代码:
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 = ""

和charToString:
charToString :: Char -> String
charToString c = [c]

它需要x并将其附加到当前。在当前的fooHelp中,将返回扩展的String

示例:foo "a4b4"然后x = "a"xs = "4b4"xs !! 0 = '4'read $ charToString( xs !! 0 ) :: Int)将char '4'转换为int 4,并将其与x(“a”)-> fooHelp(x, 4)一起传递给fooHelp并返回“aaa”。然后,x : current应该返回"aaaa",因为x = "a"和当前"aaa",然后使用++ foo tail xs进行递归调用,其中xs ="b4"应当重复此过程。

我收到错误消息:
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)
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我在哪里弄错了?我测试了fooHelp函数,它可以和foo这样的参数一起正常工作。

测试fooHelp:
xs = "4b4"

test =  read $ charToString( xs !!0 ) :: Int

*Main> test
4

最佳答案

一个典型的错误是调用像f (x1, x2)这样的函数。在Haskell中,函数只有一个参数,通常这不是一个元组。

您的fooHelper函数具有以下类型:

fooHelp :: String -> (Int -> String)

因此它是一个需要String的函数,并且返回一个将Int映射到String的函数。因此,您应该像下面这样调用函数:
(fooHelp x) (read $ charToString( xs !! 0  ) :: Int)

或更详细:
(fooHelp x) (read $ charToString( xs !! 0  ) :: Int)

但是现在类型仍然不匹配:xChar,而不是String,您可以将其包装在列表中,例如:
fooHelp [x] (read $ charToString( xs !! 0  ) :: Int)

喜欢:
foo :: String -> String
foo (x:xs) = let curent = fooHelp [x] (read $ charToString( xs !! 0  ) :: Int)
             in x : (curent) ++ foo (tail xs)

但是这个函数仍然有一个问题:我们遍历字符串,因此最终我们将到达一个空字符串,而foo没有这种情况。在这种情况下,我们需要返回空字符串,例如:
foo :: String -> String
foo (x:xs) = let curent = fooHelp [x] (read $ charToString( xs !! 0  ) :: Int)
             in x : (curent) ++ foo (tail xs)
foo [] = ""

但是它仍然不是很优雅。我们在这里执行许多不必要的操作,例如将字符包装到字符串等。

我们可以使用 replicate :: Int -> a -> [a] 函数将一个字符重复给定的次数。例如:
Prelude> replicate 3 'a'
"aaa" 

此外, digitToInt :: Char -> Int 函数可以将数字字符解析为相应的Int:
Prelude Data.Char> digitToInt '3'
3 

因此,我们可以在这里每次使用这两个字符作为字符串的前两个字符,并使用replicate (digitToInt k) x生成一个字符串,其中x si重复了请求的时间,然后对字符串的其余部分执行递归操作,例如:
import Data.Char(digitToInt)

foo :: String -> String
foo (x:k:xs) = replicate (digitToInt k) x ++ foo xs
foo _ = ""

关于haskell - haskell-无法将 ‘(Char, Int)’类型与 ‘[Char]’错误匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53067134/

相关文章:

haskell - 是否有一个标准的 Haskell 函数可以进行数值裁剪?

haskell - 使用 Haskell 镜头库,我如何将 setter/getter 视为 `first class' ?

python - 语法错误: Python keyword not valid identifier in numexpr query

python - 如果我在打印后添加冒号,为什么解释器不会抛出错误?

haskell - 为什么生成器会覆盖 Haskell 列表理解中的变量值?

haskell - 包括程序范围内的其他文件

perl - 在 perl 中使用一个值声明多个键是否有简单的语法?

json - JSON 中是否允许使用多行字符串?

go - 为什么在 Go 中使用 "redundant"关键字 "struct"作为类型?

ajax - 使用AJAX读取语法错误JSON文件