繁体   English   中英

从元组列表中获取第一个元素

[英]Get First Elements From List Of Tuples

我有一个这种格式的列表[(Int,[(Int,Int,Float)])]。 它是一个图表上的节点及其边缘列表。 列表的每个元组包含:(Node,[(startNode,endNode,Weight)])。 我喜欢做的是创建所有节点的列表。 我试过这个用过:

nodes xs = map fst xs

但它不起作用,我不知道为什么。 有什么建议么?

编辑:更具体地说,这些是我正在使用的数据结构

data Graph = G [(Node, [Edge])]

data Node = N Integer

type Edge = ( Node, Node, Float )

您需要从Graph数据类型中解包数据以对其进行操作。 最简单的方法就是做类似的事情

mapG :: ([(Node, [Edge])] -> a) -> Graph -> a
mapG f (G nodes) = map f nodes

然后你可以用它作为

> let xs = G [(N 1, []), (N 2, [])]
> mapG fst xs
[N 1, N 2]

Graph的类型不是列表,它是列表的包装器。 您可能会考虑仅使用类型别名,因为您没有使用Haskell数据类型的任何功能,更像是

type Edge = (Node, Node, Float)
type Node = Integer
type Graph = [(Node, [Edge])]

然后你可以轻松做到

> let xs = [(1, []), (2, [])] :: Graph
> :type xs
xs :: Graph
> map fst xs
[1, 2]

因此,快速浏览Haskell中的类型。 声明可以在类型签名中使用的东西有4种主要方式: typenewtypedataclass

type

最容易理解的是,任何声明为type东西都只是一个别名。 所以

type Node = Integer

Integer本身完全相同。 它可以在任何使用Integer地方使用,反之亦然。 所有这些构造都是为了使您的意图更加清晰,例如预定义的FilePath类型,它是String的别名。 如果你看到一个功能

writeToFile :: String -> String -> IO ()

相比

writeToFile :: FilePath -> String -> IO ()

你会立刻知道第二个参数是文件路径,而不必查看其他任何内容。 类型也可用于为更复杂的类型创建同义词,例如

type Edge = (Node, Node, Float)

现在你可以在任何你想要这个元组的地方编写Edge ,它更加简洁易懂。 type s也可以参数化

type List a = [a]

通过使用type ,您还可以获得所有类型化的类型类实例,例如,您可以将两个Node与常用的+一起添加并返回一个Node

newtype

type稍微强一些, newtype必须遵循特定的形式。 它们只有一个单一类型的构造函数,通常用作别名,你不希望人们真正看到里面的东西。 例如:

newtype MyInt = MyInt Int

创建一个名为MyInt的类型,它包含Int类型的单个值。 这在编译时(几乎总是)优化掉,因此一旦程序运行, MyInt占用与Int相同的内存,但在编译时MyIntInt不能互换使用。 这些在以后变得非常有用。 type s一样,它们可以参数化,但与类型不同,您不能免费获得实例。 MyInt默认不实现Num ,因此您无法将它们一起添加。

data

这是一个非常复杂的主题,所以我会说很多。 data类型是全新的,而不仅仅是别名。 它可以有一个或多个构造函数,每个构造函数需要0个或多个参数。 Bool是一个具有2个构造函数的数据类型,每个构造函数都有0个参数:

data Bool = False | True

Maybe有两个构造函数,但有一个需要参数:

data Maybe a = Nothing | Just a

在这里我们看到Maybe也参数化了。 这些data类型也不实现其内容的类型类实例,因为通常这是不可能的。 您还可以为data类型提供多个参数,例如

data Either a b = Left a | Right b

如果您有类似的数据类型

data Node = N Integer

那么IntegerNode类型不同,反之亦然。 要将Integer转换为Node ,必须使用N构造函数。 您可以将构造函数视为一种特殊的函数,甚至可以在GHCi中询问它们的类型:

> :type Just
Just :: a -> Maybe a

class

这是最抽象的一个。 类型类没有直接定义类型,而是为类型类的实例提供了一种原型。 例如, Eq类型类基本上定义为

class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool
    a /= b = not (a == b)

这里Eq说实现这个类的类型必须提供函数的定义(==) ,并且可以选择为(/=)提供定义,但是如果你不提供它,则有一个默认实现。 data Node可以实现这一点

instance Eq Node where
    (N a) == (N b) = a == b

Haskell类型系统有足够的信息,细节和扩展,您可以填写几本书,所以不要指望它以任何形式全面。 我甚至没有提到过整个主题,但这应该是一个很好的入门书。


至于生成边缘,这取决于你。 我不知道您的图表用于什么或者您希望将哪种数据放入其中,因此我认为我无法真正帮助您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM