从haskell中的输入文件中读取

时间:2012-03-17 08:33:23

标签: arrays haskell io

我正在解决Project Euler Problem 11。我已将问题中的表复制粘贴到名为“input.txt”的文件中。输入文件的每一行包含一行20x20矩阵,列用空格分隔。

我想要的是一个读取此文件的函数,并将其作为IO数组返回。我在这方面遇到了很大麻烦。

到目前为止,我已经这样做了:

import System.IO
import Control.Monad

main = readFile "input.txt"

这当然只给我输入文件的IO String表示,但我尝试的一切似乎都失败了。我该怎么办?我知道我应该做点什么

array ((1,1),(20,20)) [ the numbers tupled with their indices ]

但转换这些数字对我来说是完全不可能的,很可能是因为我还没有完全理解monad。

我相信,一旦你明白这一点,这实际上很容易。

有没有人建议做什么?

2 个答案:

答案 0 :(得分:5)

您可以使用以下内容解析文件:

s = "2 4\n6 8"

s' :: [Int]
s' = (map read . words) s

let arr = listArray ((1,1),(2,2)) s'
-- arr == array ((1,1),(2,2)) [((1,1),2),((1,2),4),((2,1),6),((2,2),8)]

wordsmap read(其中read :: (Read a) => String -> a)合并后,您会得到一个列表[Int]

因此,为了稍微组织一下,IO monad中的代码可能如下所示(假设每行具有相同的固定列数,并且您获取输入文件名,行数和列作为命令行参数):

module Main

where

import Data.Array
import Control.Monad
import System.Environment

readWords :: (Read a) => String -> [a]
readWords = map read . words

parseFile :: String -> Int -> Int -> IO (Array (Int, Int) Int)
parseFile fname rows cols = do
    matr <- liftM readWords $ readFile fname
    return $ listArray ((1, 1), (rows, cols)) matr
    -- (matr :: [Int] is inferred from the parseFile's type)

main :: IO ()
main = do
    args <- getArgs
    case args of
        [fname, rows, cols] -> do
            arr <- parseFile fname (read rows) (read cols)
            print arr

请注意转化函数readWords如何转换为[a]提供的Read a,以便我们不会仅限于整数。 liftM函数采用纯函数(我们的readWords)和&#34;提升&#34;它适用于当前的monad,即IO

答案 1 :(得分:0)

整个程序应该是这样的:

import System.IO
import Data.Array

main = do
    content <- readFile "input.txt"
    let matrix = map (map read . words) $ lines content     -- [[Int]]
    let arr = listArray ((1, 1), (20, 20)) (concat matrix)
    putStr $ solve arr

其中solveArray (Int, Int) Int -> String类型的函数。