从String中检索十进制数并将它们递归地放入[Int]列表中

时间:2015-03-18 13:39:49

标签: string list haskell recursion type-conversion

我正在通过learnyouahaskell章节工作,并一直在试验递归函数(和守卫)。我找到了一些练习,其中一个练习是从[Int]形式的String中检索十进制数。这就是我到目前为止所做的:

retrieveDecimalsFromString :: String -> [Int]
retrieveDecimalsFromString (x:xs)
    | x `elem` ['0'..'9'] = x:retrieveDecimalsFromString xs
    | otherwise = retrieveDecimalsFromString xs

这种崩溃,我理解,因为我返回的是String而不是[Int]。我似乎无法找到解决方案。也许我的方法是错的。或者(没有递归)我试过:

retrieveDecimalsFromString :: String -> [Int]
retrieveDecimalsFromString xs = filter (`elem` ['0'..'9']) xs

导致同样的问题。以上可以做到吗?

1 个答案:

答案 0 :(得分:4)

  1. 使用递归时,应该具有基本条件。在你的代码中,当字符串为空时,它会做什么?这是你的基本条件。所以,像这样改变功能定义

    retrieveDecimalsFromString :: String -> [Int]
    retrieveDecimalsFromString "" = []
    

    基本条件表示,如果输入为空字符串,我将返回一个空列表。

  2. 现在,当x是其中一个数字时,x:retrieveDecimalsFromString xs会做什么?它会尝试创建一个列表。但第一个元素xChar,根据retrieveDecimalsFromString的定义,返回值为[Int]。因此,您需要将Char转换为Int,就像这样

    retrieveDecimalsFromString (x:xs)
        | x `elem` ['0'..'9'] = (digitToInt x):retrieveDecimalsFromString xs
        | otherwise = retrieveDecimalsFromString xs
    

  3. filter版本中,您说retrieveDecimalsFromString将根据签名返回[Int],但过滤结果为[Char]。这就是为什么它不起作用。您可以通过更改这样的任何一个地方的类型来解决这个问题

    retrieveDecimalsFromString :: String -> [Char]
    retrieveDecimalsFromString xs = filter (`elem` ['0'..'9']) xs
    

    或者

    retrieveDecimalsFromString :: String -> [Int]
    retrieveDecimalsFromString xs = map digitToInt $ filter (`elem` ['0'..'9']) xs
    

    注意: digitToInt功能位于Data.Char。所以你需要在使用之前导入它。