我想写一个简单的递归函数,它有3个输入参数和1个输出参数:
getLengthOfNumber :: (String, Int, Int) -> Int
getLengthOfNumber (n, i, res)
| isCharDigit(n!!i+1) = getLengthOfNumber (n, i+1, res+1)
| otherwise = res
为什么Hugs会向我抛出错误"定义getLengthOfNumber需要Num Char的实例"?
!!
的优先级高于+
,因此n!!i+1
被解析为(n !! i) + 1
,它试图向字符串的元素添加一个,只有当Char
是数字时才有效。您应该改为编写n !! (i+1)
。
因为它解释:
n!!i+1
作为:
(n!!i) + 1
因此,它首先获得字符串的第i
个字符,然后将1
添加到其中。现在,在Haskell中,可以定义自定义数字类型。因此,在这里,可以将该字符和1
相加,但前提是该字符是数字。
但话虽如此,即使固定支架,上述方法也不会奏效。您没有指示何时停止迭代:对于字符串"123"
,它最终会获得最后一个字符,然后在到达字符串末尾时引发"索引太大"错误。此外,!!
是非有效的:它需要O(k(来访问第k个元素,使该算法成为二次型算法。
这里可以使用takeWhile :: (a -> Bool) -> [a] -> [a]
和length :: [a] -> Int
:首先取字符的最长前缀,然后取该列表的长度,如:
getLengthOfNumber :: String -> Int
getLengthOfNumber = length . takeWhile isCharDigit