【问题标题】:IO FileOffset seems pretty much uselessIO FileOffset 似乎几乎没用
【发布时间】:2015-04-07 07:04:19
【问题描述】:

我确定不是,但我从 System.Posix 函数中收到了 IO FileOffset 类型,但我不知道我能用它做什么。看起来它只是COFF类型的重命名,它似乎只是Int64的包装,实际上当我在GHCI中得到它时,我可以看到IO FileOffset对应的数字。但是,我无法将其添加到其他任何内容中、打印出来(通过解释器除外),甚至无法将其转换为另一种类型。它似乎对show 免疫。

我如何才能真正使用这种类型?我是 Haskell 的新手,所以我确定我缺少一些关于类型的基本知识,可能还有文档。

【问题讨论】:

  • 您可以将其传递给fdSeek 之类的函数,将其解包以获取底层整数,或将其用作NumIntegral 的任何其他实例
  • @n.m.:我认为 OP 对 IO FileOffset 感到困惑,而不是 FileOffset
  • 我认为可以将这个问题概括为“IO a 是什么,我该如何使用它?”,但此时问题变得(可能)过于宽泛,任何潜在的答案都会导致另一个问题单子教程。 @OP:看看单子。
  • @Zeta 或者更确切地说,看看许多避免使用 M 字的 IO 教程。
  • learnyouahaskell.com/input-and-output 展示了如何在getLine :: IO String 中使用String。您可以为您的IO FileOffset 做同样的事情。

标签: haskell


【解决方案1】:

正如在许多其他问题(例如 this)中所讨论的,从来没有您可以使用 IO a 值本身 - 除了将它绑定到另一个 IO 计算中,最终必须从mainghci 调用。这不是 Haskell 的一些愚蠢的任意限制,而是反映了这样一个事实,即文件偏移量之类的东西不可能知道,而无需程序首先“走出去”,进行文件操作,来结果回来了。在不纯的语言中,当你尝试评估一个 IO “函数”时,这种事情会突然发生,但仅仅因为半个世纪的命令式编程已经这样做了,并不意味着这是一个好主意。事实上,这是导致非纯函数式语言中大量错误的原因,但更重要的是,它使理解某些库函数实际执行的操作变得更加困难——在 Haskell 中,您只需要查看签名,以及何时存在没有IO,你可以完全确定1它不会有任何作用!

问题仍然存在:您如何真正完成任何“真正的”工作?嗯,它是pretty clever。对于初学者,遵守此指南可能会有所帮助:

  • IO 操作始终需要在 do 块中进行评估。
  • 要从此类操作中检索结果,请使用val <- action 语法。这可以位于do 块中的任何位置,除了末尾。它相当于程序语言写成var val = action() 或类似的东西。如果action 有一个类型IO T,那么val 将有一个简单的类型T
  • 以这种方式获得的值可以在您从中获得它的行下方的同一do 块中的任何位置使用。很像程序语言。

如果你的行为是,比如说,

findOffsetOfFirstChar :: Handle -> Char -> IO FileOffset

你可以这样使用它:

printOffsetOfQ :: Handle -> IO ()
printOffsetOfQ h = do
   offset <- findOffsetOfFirstChar h 'Q'
   print offset

稍后您将了解到其中许多 dos 并不是真正需要的,但目前在有 IO 的任何地方使用它们可能是最简单的。


1现在有些人会反对有一个叫做unsafePerformIO 的东西,它允许你在没有签名的情况下进行 IO,但除了是,嗯,不安全,这实际上并不属于 Haskell 语言,而是属于它的外来函数接口。

【讨论】:

  • 指出unsafePerformIO属于外来函数接口非常有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-17
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 2018-03-27
  • 1970-01-01
相关资源
最近更新 更多