我有一个大的嵌套矢量,如下所示:
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")...)
答案 0 :(得分:8)
这里有很多问题。
首先,列表推导的结果是一个列表,因此您在列表上调用Data.Vector.map
,这将无效。理解中的x
是Vector
,这是另一种类型不匹配。使用列表而不是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
轻松完成。