如何读取haskell中的文件?
我是初学者,正在尝试从我的文件夹“papers”(与脚本路径相同)中读取文件,但我遇到了下一个错误:如何读取haskell中的文件?,haskell,Haskell,我是初学者,正在尝试从我的文件夹“papers”(与脚本路径相同)中读取文件,但我遇到了下一个错误: Couldn't match expected type ‘[FilePath]’ with actual type ‘IO [FilePath]’ In the first argument of ‘leerDocumentos’, namely ‘pathFicheros’ In the first argument of ‘return’,
Couldn't match expected type ‘[FilePath]’
with actual type ‘IO [FilePath]’
In the first argument of ‘leerDocumentos’, namely ‘pathFicheros’
In the first argument of ‘return’, namely
‘(leerDocumentos pathFicheros)’
也许这不是我代码中的一个错误,所以我希望有人能帮助我完成我的模块
我的读者的代码是:
module LeerDocumentos2 where
import System.Directory
import System.IO.Unsafe
import System.IO()
import Documento
reader :: IO [Documento]
reader = do
setCurrentDirectory "papers"
directorio <- getCurrentDirectory
putStrLn directorio -- Directorio donde estan los documentos
let pathFicheros = getDirectoryContents directorio
return (leerDocumentos pathFicheros)
leerDocumentos :: [FilePath] -> [Documento]
leerDocumentos [] = []
leerDocumentos (x:xs) = do
let documento = unsafePerformIO (leerDocumento x)
[documento]++ leerDocumentos xs
leerDocumento :: String -> IO Documento
leerDocumento ruta = do
putStrLn ruta
texto <- readFile ruta
let docuAux = lines texto
let revista = obtenerRevista docuAux
let idd = obtenerID docuAux
let anno = obtenerAnno docuAux
let titulo = obtenerTitulo docuAux
let resumen = obtenerResumen docuAux
let secciones = obtenerSecciones docuAux
let documento = D (revista,idd,anno,titulo,resumen,secciones)
return documento
obtenerRevista :: [String] -> String
obtenerRevista [] = []
obtenerRevista texto = head texto
obtenerID:: [String] -> String
obtenerID [] = []
obtenerID texto = head (drop 1 (texto))
obtenerAnno:: [String] -> String
obtenerAnno [] = []
obtenerAnno texto = head (drop 2 (texto))
obtenerTitulo:: [String] -> String
obtenerTitulo [] = []
obtenerTitulo texto = head (drop 4 (texto))
obtenerResumen:: [String] -> String
obtenerResumen [] = []
obtenerResumen texto = head (drop 6 (texto))
obtenerSecciones :: [String]->[String]
obtenerSecciones [] = []
obtenerSecciones texto = quitarSeparador (drop 8 (texto))
quitarSeparador :: [String] -> [String]
quitarSeparador [] = []
quitarSeparador (s:sn) = if s == "--" || length s <= 1 then --Para quitar lineas blancas
quitarSeparador sn
else
s:quitarSeparador sn
谢谢 您遇到的问题是,您试图调用一个函数,该函数接受一个
[FilePath]
,但您正在向它传递一个IO[FilePath]
问题是要传递给函数的值被封装在IO
Monad中。每当使用输入/输出操作进行计算时,IO
Monad中就会保存一个值。在这种情况下,IO
Monad基本上是说一些IO是用来创建值的,因此调用生成值的函数可能并不总是在相同的输入上生成相同的输出
例如,函数getLines
从用户那里获取一行输入,并且由于不能保证用户每次输入的行都是相同的,因此函数返回一个IO字符串
,而不是常规的字符串
在Haskell中,您总是希望跟踪何时使用输入/输出。因此,您通常不会使用接受IO值并返回非IO值的函数,因为这会破坏重要的上下文
因此,通常不鼓励使用函数unsafePerformIO::IO a->a
,因为它执行IO操作时没有跟踪IO已执行的事实
这就是你所面临的问题背后的理论,现在你知道了,你可以想出如何处理这个问题 当使用IO值或任何其他类型的一元值时,您需要一种方法来使用一元中的值,并暂时忽略该值周围的一元上下文 有几种方法可以做到这一点。在您的例子中,您可能希望使用do符号,因为您已经在使用它了 让我们看看您遇到问题的部分:
reader :: IO [Documento]
reader = do
setCurrentDirectory "papers"
directorio <- getCurrentDirectory
putStrLn directorio -- Directorio donde estan los documentos
let pathFicheros = getDirectoryContents directorio
return (leerDocumentos pathFicheros)
问题是您试图调用leerDocumentos::[FilePath]->[Documento]
并传入类型为IO[FilePath]
的pathFicheros
,因为它是通过调用getDirectoryContents::FilePath->IO[FilePath]
获得的
您要做的是找到一种方法,将pathFicheros
作为[FilePath]
使用,但要保留IO上下文
由于所有这些都是在do块中完成的,因此可以使用=
,这将帮助您更好地了解如何使用单子,例如IO
一开始在Haskell中,单子是一个很难理解的概念,但要想更好地使用单子,最好的办法是仔细阅读它们,并尝试实现您正在阅读的想法。首先请暂时忘记,
unsafePerfomIO
甚至存在,然后使用pathFicheros
reader :: IO [Documento]
reader = do
setCurrentDirectory "papers"
directorio <- getCurrentDirectory
putStrLn directorio -- Directorio donde estan los documentos
let pathFicheros = getDirectoryContents directorio
return (leerDocumentos pathFicheros)
let pathFicheros = getDirectoryContents directorio
return (leerDocumentos pathFicheros)
pathFicheros <- getDirectoryContents directorio
return (leerDocumentos pathFicheros)