haskell:将列表列表中的一个成员从char转换为int

时间:2012-01-08 16:01:34

标签: list haskell char int

假设我有一个像这样的列表:

list= [["a","123","b"],["h","435","t"],["w","234","j"]]

我需要的是将该列表列表的每个第二个成员转换为Integer,因为它将在此之后用作大小指示符,因此我可以按大小对列表进行排序。

我想出了一个转换功能:

charToInt c = ord (chr c)

但我不知道如何转换列表中的每个第二个成员。

2 个答案:

答案 0 :(得分:6)

要扩展Paul Johnson所说的内容,您需要为您尝试保留的数据定义数据类型。

data MusicFile = MusicFile {music :: String,
                            size :: Integer,
                            artist :: String}
    deriving Show

musicFileFromStrings :: [String] -> MusicFile
musicFileFromStrings [sMusic, sSize, sArtist]
   = MusicFile sMusic (read sSize) sArtist

然后,如果你有

list = [["a","123","b"],["h","435","t"],["w","234","j"]]
你可以说

anotherList = map musicFileFromStrings list

然后

map music anotherList   -- ["a", "h", "w"]
map artist anotherList  -- ["b", "t", "j"]

(编辑)

如果您想按特定字段对列表进行排序,可以使用“sortBy”和“comparing”。

import Data.List
import Data.Ord

sizeOrderList = sortBy (comparing size) anotherList

“比较”功能将一个值(在本例中为“大小”)的函数转换为两个值之间的比较函数。唯一的要求是“size”的输出(在这种情况下)是一个“Ord”实例的类型。

如果您想降序而不是使用

sizeOrderList = sortBy (comparing (flip size)) anotherList

答案 1 :(得分:4)

您无法将内部列表的第二个元素转换为Integer,而无需将列表中的类型更改为元组之类的内容。原因是列表在Haskell中是同构的,因此您需要一个元组来表示混合类型。

String转换为Integer的方法如下:

read "123" :: Integer

您需要直接添加类型,因为read的类型为Read a => String -> a,这意味着它会返回某种类型的内容,可以是" read"。幸运的是,Integer是该类型类的成员,因此我们可以将String转换为Integer

现在转换每个内部列表的第二个元素只是一个简单的事情:

convert :: [[String]] -> [(String, Integer, String)]
convert lists = map (\[a, b, c] -> (a, read b, c)) lists