我确定没有,但我已经从IO FileOffset
函数收到了System.Posix
类型,但我无法弄明白我能做什么做它。它似乎只是COFF
类型的重命名,它似乎只是Int64
的包装,事实上当我在GHCI中得到它时,我可以看到IO FileOffset
对应。但是,我无法将其添加到其他任何内容中,将其打印出来(通过解释器除外),甚至将其转换为其他类型。它似乎不受show
的影响。
我怎样才能真正使用这种类型?我是Haskell的新手,所以我确信我错过了关于类型和文档的基本信息。
答案 0 :(得分:10)
正如许多其他问题(如this中所讨论的那样),您可以使用<{1}}值来执行从不 - 除了将其绑定在另一个IO a
中计算,最终必须从IO
或main
调用。这不是对Haskell的一些愚蠢的任意限制,而是反映了这样一个事实:像文件偏移这样的东西可能不可能知道而程序没有首先“进入世界”,进行文件操作,即将到来回到结果。在不纯的语言中,当你试图评估IO“函数”时,这种事情就会突然发生,但仅仅因为半个世纪的命令式编程以这种方式完成它并不意味着它是一个好主意。实际上它在非纯函数式语言中引起了很多错误,但更重要的是它让人更难理解一些库函数实际会做什么 - 在Haskell中你只需要查看签名,如果其中没有ghci
,你可以完全确定 1 它不会做任何事情!
问题仍然存在:你如何实际完成任何“真正的”工作?好吧,它是pretty clever。对于初学者来说,遵守本指南可能会有所帮助:
IO
块中评估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
并非真的有必要,但暂时可能最容易在任何地方使用它们{{1}继续。
1 有些人现在会反对有一个名为unsafePerformIO
的东西,允许你在没有签名的情况下做IO,但除此之外,好吧,< em> unsafe ,这实际上并不属于Haskell语言,而是属于其外部函数接口。