我对 Haskell 的类型系统有一些问题。
情况:
- 以下程序正在命令行上获取文件名列表
- 对于每个文件名,使用函数读取其内容
readFile
- 每个文件的内容都传递给
inputParser
(来自Parsec库) - 休息不是那么重要
- 主要问题在于功能
read_modules
- 表达式的前两个语句
do
在 Haskell 的类型系统中是无效的 [String]
问题是vsIO String
vs[Char]
vs ...之间的冲突- 函数
parse
应该接受 aString
但是当它得到它时,它IO String
突然想要一个(作为相同的参数),否则它想要一个String
我想要什么:
- 读取每个文件的内容
- 将该内容作为第三个参数传递给
parse
函数
这是代码:
module Main where
import System.IO
import System.Environment
import Text.ParserCombinators.Parsec
import InputParser
import Data
usage :: IO ()
usage = putStrLn "Usage: x file file file option"
parse_modules :: String -> [Char] -> Either ParseError [Module]
parse_modules filename input = parse inputParser filename input
read_modules :: [String] -> [Module]
read_modules [] = []::[Module]
read_modules (filename:rest) =
do
content <- readFile filename -- HERE is the problem
modules <- case parse_modules filename content of -- HERE is problem too
Left error -> do
putStr "parse error at "
print error
Right out -> out ++ (read_modules rest)
return modules
use :: [String] -> IO ()
use args =
do
init <- last args
filenames <- take (length args - 1) args
modules <- read_modules filenames
return ()
main :: IO ()
main = do args <- getArgs
if length args < 2
then usage
else use args
以下是 GHC 输出的错误:
ghc --make -o x.hs input-parser.hs data.hs
[3 of 3] Compiling Main ( x.hs, x.o )
x.hs:19:4:
Couldn't match expected type `IO String'
against inferred type `[String]'
In a stmt of a 'do' expression: content <- readFile filename
In the expression:
do content <- readFile filename
modules <- case parse_modules filename content of {
Left error -> do ...
Right out -> out ++ (read_modules rest) }
return modules
In the definition of `read_modules':
read_modules (filename : rest)
= do content <- readFile filename
modules <- case parse_modules filename content of {
Left error -> ...
Right out -> out ++ (read_modules rest) }
return modules
-- THIS ERROR is somewhat not important
x.hs:30:4:
Couldn't match expected type `[Char]'
against inferred type `IO Char'
Expected type: String
Inferred type: IO Char
In a stmt of a 'do' expression: init <- last args
In the expression:
do init <- last args
filenames <- take (length args - 1) args
modules <- read_modules filenames
return ()
make: *** [x] Error 1
问题是什么:
- 我不明白我应该在哪里传递 - 我有点知道我想要什么,但我不明白语法或风格。
- 我是 Haskell 的新手。
- Haskell 的类型...
有哪些问题:
- 如何解决出现的类型问题?
- 我应该投入
parse
什么——什么readFile
给了我? - 类型是否兼容?
- 不需要某种类型的转换吗?
相关网页链接:
- http://book.realworldhaskell.org/read/using-parsec.html
- http://www.zvon.org/other/haskell/Outputprelude/readFile_f.html
- http://www.haskell.org/pipermail/haskell/2002-November/010748.html
谢谢大家的提示和评论。