Haskell IO:读取整个文本文件 [英] Haskell IO: Reading the whole text file

查看:63
本文介绍了Haskell IO:读取整个文本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 导入System.IO导入Text.Printf可编码:: IO()kodable =做printf请加载地图:"文件<-getLinemapFile<-openFile文件的ReadMode让地图= loadMap [] mapFileh关闭mapFileprintf成功读取地图!\ n"printf初始:\ n"outputMap地图loadMap :: [String]->FilePath->[细绳]loadMap map fp =做成品<-hIsEOF fpnew_map<-如果尚未完成然后映射++ [hGetLine fp]否则返回()loadMap new_map fpoutputMap :: [String]->IO()outputMap(x)= printf%s \ n";XoutputMap(x:xs)=做printf%s \ n"XoutputMap xs 

我正在从事一个项目,该项目需要首先从txt文件(例如"map.txt")将地图加载到游戏中.可编码是主要功能.首先,游戏将要求玩家加载地图.因此,在这种情况下,播放器将输入 map.txt .然后,我尝试使用功能 loadMap 将地图递归地放入字符串数组并存储在 map 中.最后,我将使用功能 outputMap 输出我已加载的地图.由于我仍然是Haskell的初学者,因此在调试此部分时遇到了麻烦.

解决方案

我看到您已经决定坚持第一个答案.但是我只想在这里提出这个解决方案,以便您对未来有一个想法.我将使用一些复杂"的到目前为止,您可能无法使用的功能.

首先,可以将 kodable 简化为:

  kodable :: IO()kodable = getMapFile>> = readFile>> = outputMap 

时髦的>> = 函数只是处理IO Monad的一种方式,因此我们不必解包和包装值.我将不赘述,因为它超出了这个问题的范围.

  getMapFile :: IO字符串getMapFile = putStr请加载地图:">>getLine 

此函数所做的全部工作是打印出提示,然后获取键入的任何内容.>> 只是忽略了左侧的返回值.

readFile 可以完成您所期望的工作,它从getMapFile中获取文件名并读取文件的内容.

  outputMap :: String->IO()outputMap = mapM_ putStrLn.线-  或者outputMap ::字符串->IO()outputMap fileContents = mapM_ putStrLn $行fileContents 

此处的最终功能与代码中的 loadMap outputMap 完全相同. lines 等效于 loadMap ,它根据换行符将输入文件拆分为单独的字符串.我知道您正在尝试递归思考并只是学习,但是有许多有用的功能可以使您的生活更轻松.

将文件内容分成几行后,我们可以使用Monadic Map函数 mapM _ ,该函数实际上将 putStrLn 应用于列表中的每一行./p>

import System.IO

import Text.Printf

kodable :: IO()
kodable = do
    printf "Please load a map : "
    file <- getLine
    mapFile <- openFile file ReadMode
    let map = loadMap [] mapFile
    hClose mapFile
    printf "Read map successfully! \n"
    printf "Initial:\n"
    outputMap map
    
loadMap :: [String] -> FilePath -> [String]
loadMap map fp = do
    finished <- hIsEOF fp
    new_map <- if not finished
               then map ++ [hGetLine fp]
               else return ()
    loadMap new_map fp
    
outputMap :: [String] -> IO()
outputMap (x) = printf "%s\n" x
outputMap (x:xs) = do
    printf "%s\n" x
    outputMap xs

I am working on a project which need to load a map into the game first from a txt file, eg "map.txt". The kodable is the main function. First, the game will ask the player to load a map. So, in that case, the player will input map.txt. Then, I am trying to use the function loadMap to recursively put the map into array of string and stored in map. Finally, I will use the function outputMap to output the map I have load. As I am still a beginner in Haskell, so I am having trouble in debugging this part.

解决方案

I see that you have already decided on sticking with your first answer. But I just would like to throw this solution here, just so you have an idea for the future. I will be using some "complex" functions that are probably out of your reach as of now.

Firstly, kodable can be reduced to:

kodable :: IO ()
kodable = getMapFile >>= readFile >>= outputMap

The funky >>= function is just a way to deal with the IO Monad so we don't have to unwrap and wrap values. I won't go into details because its out of the scope of this question.

getMapFile :: IO String
getMapFile = putStr "Please load a map: " >> getLine

All this function does is print out the prompt and then get whatever input is typed in. The >> simply ignores the returned value on the left.

readFile does what you expect, it takes the filename from getMapFile and reads the contents of a file.

outputMap :: String -> IO ()
outputMap = mapM_ putStrLn . lines

-- OR 

outputMap :: String -> IO ()
outputMap fileContents = mapM_ putStrLn $ lines fileContents

The final function here does exactly what loadMap and outputMap do in your code. lines is equivalent to loadMap, it splits the input file into separate strings based on newline characters. I get that you are trying to think recursively and just learning, but there are many useful functions out there to make your life easier.

After the contents of the file are split into the lines, we can use the Monadic Map function mapM_, which essentially applies putStrLn to every line in the list.

这篇关于Haskell IO:读取整个文本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆