Parsing 读取文件的奇怪行为

Parsing 读取文件的奇怪行为,parsing,haskell,io,Parsing,Haskell,Io,我正在用哈斯克尔写一个程序 这是代码 module Main where import IO import Maybe import Control.Monad.Reader --il mio environment consiste in una lista di tuple/coppie chiave-valore data Environment = Env {variables::[(String,String)]}deriving (Show) fromEnvToPair :: En

我正在用哈斯克尔写一个程序 这是代码

module Main
where
import IO
import Maybe
import Control.Monad.Reader
--il mio environment consiste in una lista di tuple/coppie chiave-valore
data Environment = Env {variables::[(String,String)]}deriving (Show)

fromEnvToPair :: Environment-> [(String,String)]
fromEnvToPair (Env e)= e

estrai' x d
|length x==0=[]
|otherwise=estrai x d
estrai (x:xs) d
| (x:xs)=="" =[]
| x== d=[]
| otherwise = x:(estrai  xs d)
--estrae da una stringa tutti i caratteri saino a d
conta'  x d n 
| length x==0 = 0
|otherwise = conta x d n 
conta (x:xs) d n
| x== d=n
| otherwise = (conta  xs d (n+1))
primo (a,b,c)=a
secondo (a,b,c)=b
terzo (a,b,c)=c

estraifrom x d n
|n>=(length x) =[]
| x!!n==d = []
|otherwise = x!!n:(estraifrom x d (n+1))

readerContent :: Reader Environment Environment
readerContent =do
content <- ask
return ( content)

-- resolve a template into a string
resolve :: [Char]-> Reader Environment (String)
resolve key= do
varValue <- asks (lookupVar key)
return $ maybe "" id varValue

maketuple x =(k,v,l) where
k= (estrai' x ':')--usare estrai'

v=estraifrom x ';' (conta' x ':' 1)
l= (length k)+(length v)+2 --è l'offset dovuto al; e al :
makecontext x
| length x==0 = []
| (elem ':' x)&&(elem ';' x)==False = []
|otherwise= (k,v):makecontext (drop l x) where
    t= maketuple x
    k= primo t
    v= secondo t
    l= terzo t



doRead filename = do
    bracket(openFile filename ReadMode) hClose(\h -> do 
        contents <- hGetContents h 
        return contents
        let cont=makecontext contents
        putStrLn (take 100 contents)
        return (contents))
--          putStrLn (snd (cont!!1)))
--          putStrLn (take 100 contents))


-- estrae i caratteri di una stringa dall'inizio fino al carattere di controllo
-- aggiungere parametri to the environment

-- estrae i caratteri di una stringa dall'inizio fino al carattere di controllo
-- aggiungere parametri to the environment



-- lookup a variable from the environment
lookupVar :: [Char] -> Environment -> Maybe String
lookupVar name env = lookup name (variables env)
lookup'  x t=[v| (k,v)<-t,k==x]





fromJust' :: Maybe a -> a
fromJust' (Just x) = x
fromJust' Nothing  = error "fromJust: Nothing"

main = do

file<- doRead "context.txt"-- leggo il contesto
let env= Env( makecontext file) -- lo converto in Environment
let c1= fromEnvToPair(runReader readerContent env)
putStrLn(fromJust'(lookupVar "user" env))
--putStrLn ((lookup' "user" (fromEnvToPair env))!!0)-- read the environment
--putStrLn ("user"++ (fst (c1!!1)))
putStrLn ("finito")
--putStrLn("contesto" ++ (snd(context!!1)))
主模块
哪里
输入IO
也许是进口
导入控制.Monad.Reader
--乌纳利斯塔二元/铜交叉谷的环境
数据环境=环境{变量::[(字符串,字符串)]}派生(显示)
fromEnvToPair::环境->[(字符串,字符串)]
fromEnvToPair(环境e)=e
埃斯特拉伊x d
|长度x==0=[]
|否则=i x d
埃斯特拉伊(x:xs)d
|(x:xs)==“”=[]
|x==d=[]
|否则=x:(estrai xs d)
--这是一个很好的例子
续
|长度x==0=0
|否则=conta x d n
续(x:xs)d n
|x==d=n
|否则=(续xsd(n+1))
primo(a,b,c)=a
第二(a,b,c)=b
terzo(a,b,c)=c
雌二醇
|n> =(长度x)=[]
|x!!n==d=[]
|否则=x!!n:(雌二醇x d(n+1))
readerContent::Reader环境
readerContent=do
内容阅读器环境(字符串)
解析键=do
varValue do
内容环境->可能是字符串
lookupVar name env=查找名称(变量env)

lookup'x t=[v |(k,v)我认为问题在于惰性。在实际读取该内容之前,文件句柄已关闭。通过在关闭句柄之前获取并打印一些内容,您可以强制它在返回/关闭句柄之前加载


我建议使用
System.IO.Strict
中的
readFile
函数。它严格加载内容(非惰性),并且它还节省了使用文件句柄时的一些麻烦。您只需将对doRead的调用替换为readFile,因为它具有相同的类型签名。

使用Haskell解析器库可以使此类操作更轻松,更容易出错。下面是一个如何使用readFile执行此操作的示例:

我们可以按如下方式测试解析器:

*Main> Just env <- parseEnvironment <$> B.readFile "context.txt"
*Main> print $ M.lookup "user" env
Just "somebody"
*Main> print env
fromList [("home","somewhere"),("user","somebody"),("x","1"),("y","2"),("z","3")]
*Main>Just env print$M.lookup“user”env
只是“某人”
*主>打印环境
fromList[(“家”、“某处”)、(“用户”、“某人”)、(“x”、“1”)、(“y”、“2”)、(“z”、“3”)]
请注意,正如camcann在对您先前的
读者
单子问题的评论中所建议的那样,我正在使用
地图
来表示环境

user: somebody;
home: somewhere;
x: 1;
y: 2;
z: 3;
*Main> Just env <- parseEnvironment <$> B.readFile "context.txt"
*Main> print $ M.lookup "user" env
Just "somebody"
*Main> print env
fromList [("home","somewhere"),("user","somebody"),("x","1"),("y","2"),("z","3")]