将[String]列表转换为Haskell中的[Double]列表

时间:2014-11-23 23:23:54

标签: haskell

我正在编写一个函数来将String列表(从CSV文件中读取)转换为双打列表。它在第3行给出了一个错误。

stringToDouble :: [String] -> [Double]
stringToDouble [] = error "empty list"
stringToDouble [x] = read x :: Double -- the `read` gives me an error
stringToDouble (x:xs) = stringToDouble xs

是不是因为我没有将转换后的Double放入需要返回的列表中?

2 个答案:

答案 0 :(得分:8)

错误源于read x属于Double类型,而不是[Double]这一事实,但是,即使使用该修复程序,您的功能也无法正常工作。

让我们把你的函数放到单词中:“获取字符串列表的前面元素,将其作为双精度读取,然后对列表的其余部分执行相同操作”。现在让我们来看看你的功能:

stringToDouble :: [String] -> [Double]
stringToDouble [] = error "empty list"
stringToDouble [x] = read x :: Double -- Error
stringToDouble (x:xs) = stringToDouble xs

现在让我们将修复程序应用于它。此外,没有理由在空列表中出错;只是屈服和空双打名单:

stringToDouble :: [String] -> [Double]
stringToDouble [] = []
stringToDouble [x] = [read x :: Double] -- Put the single value into a list
stringToDouble (x:xs) = stringToDouble xs

问题在于递归步骤。在列表上调用stringToDouble与在列表尾部调用stringToDouble相同。第一个元素被简单地丢弃。您想转换头并将其放回列表中。

stringToDouble :: [String] -> [Double]
stringToDouble [] = []
stringToDouble [x] = [read x :: Double] -- Put the single value into a list
stringToDouble (x:xs) = (read x :: Double) : stringToDouble xs

其中(:)是用于将元素附加到列表前面的运算符。由此,甚至不需要中间行,因为递归步骤将处理转换,空列表步骤将处理停止条件。

stringToDouble :: [String] -> [Double]
stringToDouble [] = []
stringToDouble (x:xs) = (read x :: Double) : stringToDouble xs

现在,实际上,你可能可能删除:: Double部分,而Haskell会根据函数的类型约束找出你的意思,但它不会受到伤害,有时它会有助于将其留在其中。

答案 1 :(得分:1)

你是对的 - read x :: DoubleDouble类型,而函数的返回类型是[Double]类型(意思是" {{1}列表1}}&#34)

这样的事情:

Double

应该有用。

请注意,如果您尝试单独转换列表中的每个元素,则应使用stringToDouble [x] = [read x :: Double] 编写函数,而不是使用显式递归。如果map的类型为f,则String -> Double将是map f类型的函数。