Haskell - 从文件读取到特定数组

时间:2016-01-31 19:09:24

标签: file haskell

我有一个像这样定义的Garph:

type Edge = (Int, Int)
type Graph = [Edge]

我也有节点列表:

nodes :: [Int]

我拥有图表的所有节点。 我想从文件中读取这些节点和图形,但我只能使用Prelude,System.IO和System.Enviorment。 我已经尝试了一些东西但是我以后无法在该列表上工作。

我的文件看起来像

[1,2,3,4,5,6]
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)]

但如果它更易于阅读,我可以更改它。如果有人能帮助我,我将不胜感激。

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

getFirstLine input = head (lines input)

start :: IO()
start = do
    contents <- readFile "test.txt"
    let nodes =  getFirstLine contents

但它不起作用 我想将这些节点分配给我的

nodes :: [Int]
nodes = []

所以我可以使用列表中可用的函数

@ EDIT2

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

1 个答案:

答案 0 :(得分:4)

因此该文件由两行组成,每行都需要单独读取。

首先,让我们得到前两行:

firstTwoLines :: [String] -> (String, String)
firstTwoLines (x1:x2:_) = (x1,x2)

现在您可以将两行读作单独的变量

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

“阅读”的类型是:

read :: (Read a) => String -> a

换句话说,您正在阅读的类型必须是“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

显然,您可以通过任何图形处理替换最后两行,但这足以确认您正在正确读取文件。