我正在编写扩展字符串的函数
例:
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)
但是现在类型仍然不匹配:
x
是Char
,而不是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/