File Haskell-从文件读入特定数组

File Haskell-从文件读入特定数组,file,haskell,File,Haskell,我有一个Garph的定义如下: type Edge = (Int, Int) type Graph = [Edge] 我还有一个节点列表: nodes :: [Int] 我有我的图的所有节点。 我想从文件中读取这些节点和图形,但我只能使用Prelude、System.IO和System.environment。 我试过一些东西,但以后无法处理这些列表 我的文件看起来像 [1,2,3,4,5,6] [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)]

我有一个Garph的定义如下:

type Edge = (Int, Int)
type Graph = [Edge]
我还有一个节点列表:

nodes :: [Int]
我有我的图的所有节点。 我想从文件中读取这些节点和图形,但我只能使用Prelude、System.IO和System.environment。 我试过一些东西,但以后无法处理这些列表

我的文件看起来像

[1,2,3,4,5,6]
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)]
但如果能更容易阅读的话,我可以改一下。如果有人能帮助我,我将不胜感激

@编辑 从文件中读取看起来像这样

getFirstLine input = head (lines input)

start :: IO()
start = do
    contents <- readFile "test.txt"
    let nodes =  getFirstLine contents
所以我可以使用列表可用的函数

@编辑2

start :: IO()
start = do
    contents <- readFile "test.txt"
    let (line1, line2) = firstTwoLines $ lines contents
        nodes = readNodes line1
        edges = readEdges line2
    print nodes
    print edges
    print nodes
    print graph
    print hamiltonianCycles nodes
    print eulerianCycles
start::IO()
开始=做

内容因此文件由两行组成,每一行都需要单独读取

首先,让我们看一下前两行:

firstTwoLines :: [String] -> (String, String)
firstTwoLines (x1:x2:_) = (x1,x2)
现在,您可以将这两行作为单独的变量读取

从字符串到[Integer](或任何其他类型)的转换由“read”函数完成。如果字符串与预期格式不匹配,则会引发异常。每种类型都有自己的“read”函数,因此您需要确定所需的类型

“读取”类型为:

换句话说,您正在读取的类型必须是“Read”类的实例。所有基本类型都是“Read”的实例,元组和实例列表也是实例。换句话说,“阅读”可以处理你的两行

所以你可以

readNodes :: String -> [Int]
readNodes = read

readEdges :: String -> Graph
readEdges = read
通过对返回类型的具体说明,我们使每个调用都成为“read”的正确实现。您可以隐式地执行此操作,但如果您犯了错误,您只会在运行时得到一个“无解析”异常,并且不知道原因

现在你可以写作了

main = do
   contents <- readFile "test.txt"
   let (line1, line2) = firstTwoLines $ lines contents
       nodes = readNodes line1
       edges = readEdges line2
   print nodes
   print edges
main=do

内容我试着使用我编辑过的文章“它不起作用”。什么不起作用?症状是什么?我最近收到了不同的错误“do{…}中的最后一个生成器必须是定义main所需的Num[Char]的表达式‘有时也是’实例”当我将它放入另一个文件时它可以工作,但如果我将它与另一个代码一起使用,那么我得到“do{…}中的最后一个生成器必须是表达式”@Meii“do中的最后一个生成器必须是表达式”是关于“do”子句的。您不能将“let”子句作为“do”中的最后一项,因为“do”本身必须有一个值。您可能希望“return(nodes,edges)”,或者在“let”中计算更多内容,然后打印结果。顺便说一句,“print nodes”返回一个“IO()“值,它仍然是一个返回值。它不是关于在末尾有let,我将我的start函数添加到我的帖子中,我在末尾没有let,但我仍然有那个错误。在我从文件中添加读取图形之前,这一切都起了作用,但我必须读取它。如果我删除一些空白,我会在应用程序中得到另一个错误“类型错误***表达式:打印哈密顿循环节点***术语:打印***类型:d->IO()***不匹配:a->b->c;我能以某种方式使边和节点成为全局的,这样就不必将其作为参数传递吗?因为它在您可能需要说“print$hamiltonian节点”之前就已经起作用了。但是如果你发布了你遇到困难的代码,这会有所帮助。另外,请注意,空格在Haskell中很重要。
readNodes :: String -> [Int]
readNodes = read

readEdges :: String -> Graph
readEdges = read
main = do
   contents <- readFile "test.txt"
   let (line1, line2) = firstTwoLines $ lines contents
       nodes = readNodes line1
       edges = readEdges line2
   print nodes
   print edges