我想编写一个简单的具有3个输入参数和1个输出参数的递归函数:
getLengthOfNumber :: (String, Int, Int) -> Int
getLengthOfNumber (n, i, res)
| isCharDigit(n!!i+1) = getLengthOfNumber (n, i+1, res+1)
| otherwise = res
为什么拥抱会向我抛出错误“定义getLengthOfNumber所需的Num Char实例”?
答案 0 :(得分:3)
!!
的优先级比+
高,因此n!!i+1
被解析为(n !! i) + 1
,它试图将一个添加到字符串元素中,仅在{ {1}}是一个数字。您应该改写Char
。
答案 1 :(得分:2)
因为它解释:
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