【问题标题】:How does Haskell's putStrLn perform its effect? [duplicate]Haskell 的 putStrLn 是如何发挥作用的? [复制]
【发布时间】:2019-05-13 17:51:48
【问题描述】:

我想知道 putStrLn 是如何工作的:我可以看到它的类型为 IO (),但我不知道 Haskell 是如何实际执行写入标准输出的副作用的。

main :: IO ()
main = putStrLn "Test"

这个程序如何写入标准输出?

【问题讨论】:

    标签: haskell io


    【解决方案1】:

    使用 C

    看到base那个

    putStrLn s      =  hPutStrLn stdout s
    

    我跟踪了一系列函数,最终将我引向c_write,其定义如下:

    foreign import capi unsafe "HsBase.h _write"
      c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
    

    这样看来,写入stdout的效果是通过调用native code来实现的。


    在我从一个函数跳到另一个函数的旅程中的一些停靠点(箭头→表示左边的函数调用右边的函数):

    hPutStr'writeBlockscommitBufferwriteCharBuffer

    然后,writeCharBufferstdout 上调用类型类方法BufferedIO.flushWriteBuffer

    stdout's typeclass instance 继续BufferedIO

    flushWriteBufferwriteBuf'writeBufwriteBufRawIO 设备上调用IODevice.write,这也是一个有instance for stdout 的类型类。 write 中继到fdwrite

    fdWrite 调用writeRawBufferPtrdo_write 最后调用c_write

    【讨论】:

    • putStrLn 是唯一由 Haskell 定义的东西。下面的所有内容,在本例中从hPutStrLn 开始,都是 GHC 的实现细节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2013-10-17
    • 2022-01-20
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    相关资源
    最近更新 更多