标签: lazy-io

导致这种"关闭手柄延迟读取"错误的原因是什么?

我刚刚从最新的来源安装了GHC,现在我的程序给了我一个关于"关闭句柄的延迟读取"的错误消息.这是什么意思?

haskell ghc lazy-io

7
推荐指数
1
解决办法
694
查看次数

Haskell:隐藏懒惰IO中的失败

这是一个菜鸟问题.

我想写一个提供懒惰图像流的函数,大概是这样的:

imageStream :: [IO Image]
Run Code Online (Sandbox Code Playgroud)

不幸的是,读取图像的功能可能会失败,所以它看起来像:

readImage :: IO (Maybe Image)
Run Code Online (Sandbox Code Playgroud)

所以,我写的功能如下:

maybeImageStream :: [IO (Maybe Image)]
Run Code Online (Sandbox Code Playgroud)

如何在保持惰性IO的同时实现如下功能?

flattenImageStream :: [IO (Maybe Image)] -> [IO Image]
Run Code Online (Sandbox Code Playgroud)

从语义上讲,当您要求flattenImageStream下一个图像时,它应该遍历列表并尝试读取每个图像.它会在找到加载并返回的图像之前执行此操作.

编辑:答案中似乎存在一些分歧.有些人建议使用的解决方案sequence,但我很确定我测试了它,并发现它破坏了懒惰.(我会再次测试它,以确保我何时回到我的电脑.)有人还建议使用unsafeInterleaveIO.从该函数的文档来看,它似乎可行,但显然我想尽可能地尊重类型系统.

haskell lazy-io

6
推荐指数
1
解决办法
166
查看次数

使用getChar重新实现getContents

在我对Haskell中抓住懒惰IO的哀悼中,我尝试了以下方法:

main = do
  chars <- getContents
  consume chars

consume :: [Char] -> IO ()
consume [] = return ()
consume ('x':_) = consume []
consume (c : rest) = do
  putChar c
  consume rest
Run Code Online (Sandbox Code Playgroud)

它只是回显了所有在stdin中键入的字符,直到我点击'x'.

所以,我天真地认为应该可以getContents通过getChar以下几点做一些事情来重新实现:

myGetContents :: IO [Char]
myGetContents = do
  c <- getChar
  -- And now?
  return (c: ???) 
Run Code Online (Sandbox Code Playgroud)

事实证明它不是那么简单,因为它???需要一个类型的功能IO [Char] -> [Char]- 我认为 - 打破IO monad的整个想法.

检查getContents(或更确切地说hGetContents)的实施揭示了整个香肠工厂的脏IO东西.我的假设是否正确,myGetContents如果不使用脏的,即monad-breaking代码, 就无法实现?

haskell lazy-io

6
推荐指数
1
解决办法
170
查看次数

monadic动作的懒惰输出

我有下一个monad变换器:

newtype Pdf' m a = Pdf' {
  unPdf' :: StateT St (Iteratee ByteString m) a
  }
type Pdf m = ErrorT String (Pdf' m)
Run Code Online (Sandbox Code Playgroud)

基本上,它使用底层 Iteratee来读取和处理pdf文档(需要随机访问源,因此它不会一直将文档保存在内存中).

我需要实现一个保存pdf文档的函数,我希望它是懒惰的,应该可以将文档保存在常量内存中.

我可以生产懒惰ByteString:

import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as BS
save :: Monad m => Pdf m ByteString
save = do
  -- actually it is a loop
  str1 <- serializeTheFirstObject
  storeOffsetForTheFirstObject (BS.length str1)
  str2 <- serializeTheSecondObject
  storeOffsetForTheSecondObject (BS.length str2)
  ...
  strn <- serializeTheNthObject
  storeOffsetForTheNthObject (BS.length strn)
  table <- dumpRefTable
  return …
Run Code Online (Sandbox Code Playgroud)

haskell lazy-io

5
推荐指数
1
解决办法
311
查看次数

在Haskell中同时读取和写入同一文件时出错

我需要就地修改文件.所以我打算读取文件内容,处理它们,然后将输出写入同一个文件:

main = do
  input <- readFile "file.txt"
  let output = (map toUpper input) 
  -- putStrLn $ show $ length output
  writeFile "file.txt" output
Run Code Online (Sandbox Code Playgroud)

但问题是,只有当我取消注释第4行时才会按预期工作 - 我只是输出字符数到控制台.如果我不取消注释,我会得到

openFile: resource busy (file is locked)
Run Code Online (Sandbox Code Playgroud)

有没有办法强制阅读该文件?

file-io haskell locking lazy-evaluation lazy-io

5
推荐指数
1
解决办法
278
查看次数

Haskell懒惰的字节串字不懒惰?

我有以下Haskell程序用于计算整数字符串的最大和子串:

{-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -O2 #-}
import Data.Functor
import Data.Maybe 
import Data.ByteString.Lazy.Char8 (getContents,lines,readInt,words)
import Prelude hiding (getContents,words,lines)

main = do
    cont <- words <$> getContents
    putStrLn $ show $ snd $ foldl opt (0,0) $ map (fst.fromJust.readInt) cont

opt (!c,!m) x = (max 0 (c+x),max m (c+x))
Run Code Online (Sandbox Code Playgroud)

该程序的问题在于它将整个文件读入内存.没有BytesString的相应程序没有这个问题:

{-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -O2 #-}
import Data.Functor
import Data.Maybe 

main = do
    cont <- words <$> getContents
    putStrLn $ show $ snd $ foldl opt (0,0) …
Run Code Online (Sandbox Code Playgroud)

haskell long-lines bytestring lazy-io

3
推荐指数
1
解决办法
279
查看次数

防止"getCurrentDirectory:资源耗尽(打开文件太多)"错误

我试图在Parsec一大堆小文件上运行一个解析器,并收到一条错误,说我有太多打开的文件.我知道我需要使用严格的IO,但我不知道该怎么做.这是有问题的代码:

files = getDirectoryContents historyFolder

hands :: IO [Either ParseError [Hand]]
hands = join $ sequence <$> parseFromFile (many hand) <<$>> files
Run Code Online (Sandbox Code Playgroud)

注意:我的<<$>>功能是这样的:

(<<$>>) :: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
a <<$>> b = (a <$>) <$> b
Run Code Online (Sandbox Code Playgroud)

haskell parsec lazy-evaluation lazy-io

3
推荐指数
1
解决办法
724
查看次数

为什么不打印强制整个惰性 IO 值?

我正在使用http-client教程使用 TLS 连接获取响应正文。既然我可以观察到它print是由 调用的withResponse,为什么不print强制对以下片段中的输出进行完整响应?

withResponse request manager $ \response -> do
    putStrLn $ "The status code was: " ++
    body <- (responseBody response)
    print body
Run Code Online (Sandbox Code Playgroud)

我需要写这个:

response <- httpLbs request manager

putStrLn $ "The status code was: " ++
           show (statusCode $ responseStatus response)
print $ responseBody response
Run Code Online (Sandbox Code Playgroud)

我要打印的正文是一个懒惰的 ByteString。我仍然不确定是否应该print打印整个值。

instance Show ByteString where
    showsPrec p ps r = showsPrec p (unpackChars ps) r
Run Code Online (Sandbox Code Playgroud)

haskell conduit lazy-io haskell-pipes http-conduit

2
推荐指数
1
解决办法
212
查看次数

使用文本而不是字符串的“交互”

我想重写该interact函数,但使用Text代替String。是否可以使用Data.Text和/或Data.Text.Lazy完成与相同的行为interact

例如,当我使用来运行该程序时String

main = interact (unlines . map f . lines)
  where f "hello" = "wassup"
        f _ = "wat?"
Run Code Online (Sandbox Code Playgroud)

它等待一行输入,然后打印出一行作为响应,并等待下一行输入。我想编写相同的代码并使其工作Text

{-# LANGUAGE OverloadedStrings #-}
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as T

textInteract :: (Text -> Text) -> IO ()
textInteract = undefined

main = textInteract (T.unlines . map f . T.lines)
  where f "hello" = "wassup"
        f _ = "wat?"
Run Code Online (Sandbox Code Playgroud)

但是,不只是textInteract …

text haskell lazy-io

1
推荐指数
1
解决办法
231
查看次数