如何从Haskell中的文件解析矩阵?

时间:2014-05-26 09:11:27

标签: file haskell matrix handle

我是Haskell的新人 我试图用两个矩阵解析一个文本文件。文本文件的内部:

    m n
    a11 a12 ...
    a21 a22 ...
    ...
    b11 b12 ...
    b21 b22 ...
    ...

其中m是第一矩阵的行数,n是第二矩阵的行数 例如:

        3 2
        1 2 3
        4 5 6
        7 8 9
        1 2
        3 4

我知道,看起来很愚蠢,但我有一个任务解析一个带有2个矩阵的文本文件,我只想出来了。
有代码:

readLine :: Read a => Handle -> IO [a]
readLine = fmap (map read . words) . hGetLine

parse :: Handle -> IO (Matrix a, Matrix a)
parse = do
    [m, n] <- readLine
    xss1    <- replicateM m readLine
    xss2    <- replicateM n readLine
    return (fromLists xss1, fromLists xss2)

main = do
  [input, output] <- getArgs
  h <- openFile input ReadMode
  (m1, m2) <- parse h
  print $ mult m1 m2

控制台有一个日志:

Prelude> :r
[1 of 1] Compiling Matrix           ( lab.matrix.hs, interpreted )

lab.matrix.hs:156:5:
    Couldn't match expected type `IO [a0]' with actual type `[t0]'
    In the pattern: [m, n]
    In a stmt of a 'do' block: [m, n] <- readLine
    In the expression:
      do { [m, n] <- readLine;
           xss1 <- replicateM m readLine;
           xss2 <- replicateM n readLine;
           return (fromLists xss1, fromLists xss2) }
Failed, modules loaded: none.

最有可能的是,仍有一些错误 请帮助我,我已经筋疲力尽......

1 个答案:

答案 0 :(得分:4)

您需要为Handle的每次调用提供readLine作为参数,因此parse可能如下所示:

parse h = do
    [m, n] <- readLine h
    xss1 <- replicateM n $ readLine h
    xss2 <- replicateM m $ readLine h
    return (fromLists xss1, fromLists xss2)

另一个注意事项 - 检查getArgs返回的参数数量可能更安全,而不是假设会有两个。例如:

main = do
    args <- getArgs
    case args of
        [input, output] -> do
             h <- openFile input ReadMode
             (m1, m2) <- parse h
             hClose h
             print $ show mult m1 m2
        _ -> putStrLn "expected two arguments"