如何将函数应用于向量列表?

时间:2012-03-25 16:37:46

标签: haskell vector

我有一个大的嵌套矢量,如下所示:

import Data.Vector
let x = fromList [["a", "b", "12", "d"], ["e", "f", "34", "g"]...]

我想将字符串转换为每个嵌套列表中位置2的整数我试图用map和这样的理解来做到这一点:

let y = Data.Vector.map (\a -> read a :: Int) [i !! 2 | i <- x]

我做错了什么?我希望输出为:

(("a", "b", 12, "d"), ("e", "f", 34, "g")...)

2 个答案:

答案 0 :(得分:8)

这里有很多问题。

首先,列表推导的结果是一个列表,因此您在列表上调用Data.Vector.map,这将无效。理解中的xVector,这是另一种类型不匹配。使用列表而不是Vector(以及Prelude.map)或将列表转换为Vector(在这种情况下,您不能使用列表推导)。

其次,忽略列表/ Vector问题,[i !! 2 | i <- x]将为您提供一个列表,其中仅包含每个子列表中位置2的元素。使用您的示例,理解将产生["12", "34"]。然后,当您将read映射到它时,您将获得[12, 34],而不是您正在拍摄的输出。

最后,您想要查看的输出对于列表或Haskell中的Vectors无效。两种类型的容器必须是同质的,即它们不能包含多于一种类型的值。 [Int]不能包含String[String]也不能包含Int,但您想要的输出包含[(String, String, String, String)]。有一些方法可以使用存在类型来解决这个问题,但是对于您的潜在问题而言,有可能比尝试构建异构集合更好。

编辑:您编辑了帖子的最后一部分以使用元组,因此上述段落不再适用。不过,我提到的前两个问题仍然存在。

如果你从一个4元组列表(> let x = [("a", "b", "12", "d"), ("e", "f", "34", "g")] > map (\(a, b, c, d) -> (a, b, read c :: Int, d)) x [("a", "b", 12, "d"), ("e", "f", 34, "g")] )开始,你可以得到你想要的东西:

{{1}}

答案 1 :(得分:1)

看起来你应该使用比4元组更复杂的数据类型,比如

data YourType_StringNum = YourType_StringNum { ytsnLetters1 :: String
                                             , ytsnLetters2 :: String
                                             , ytsnNumber :: String
                                             , ytsnLetters3 :: String }
data YourType_IntNum = YourType_IntNum { ytinLetters1 :: String
                                       , ytinLetters2 :: String
                                       , ytinNumber :: Int
                                       , ytinLetters3 :: String }

(当然有更好的标识符)。然后定义一个像

这样的函数
toYtin :: YourType_StringNum -> YourType_IntNum
toYtin(YourType_StringNum a b s c) = YourType_IntNum a b (read s) c

通过这种方式,您的问题会缩短为将Vector YourType_StringNum转换为Vector YourType_IntNum,并且可以通过Data.Vector.map toYtin轻松完成。