Haskell primPutChar 定义

标签 haskell io definition

我试图弄清楚基本的IO Haskell 函数是定义好的,所以我使用了this reference我到了putChar函数定义:

putChar    :: Char -> IO ()
putChar    =  primPutChar

但是,现在我找不到关于此 primPutChar 的更多信息。随时随地发挥作用。也许它可能指的是预编译的函数,可作为共享对象的二进制文件?如果是这样,是否可以看到它的源代码?

最佳答案

什么prim*方法

既然你是从报告的角度来问这个问题,那么我们也从报告的角度来回答这个问题:

Primitives that are not definable in Haskell , indicated by names starting with "prim", are defined in a system dependent manner in module PreludeBuiltin and are not shown here



这在 Haskell2010 by the way 中仍然相同。 .

它是如何在 GHC 中实现的

但是,您可以 have a look at base 's source看看它是如何在 GHC 中实现的:
putChar         :: Char -> IO ()
putChar c       =  hPutChar stdout c

从那里你将深入兔子洞。 hPutChar 如何知道怎么打印东西吗?好吧,它没有。它仅“缓冲”并检查您是否可以编写:
hPutChar :: Handle -> Char -> IO ()
hPutChar handle c = do
    c `seq` return ()
    wantWritableHandle "hPutChar" handle $ \ handle_  -> do
     hPutcBuffered handle_ c

写作完成于 writeCharBuffer 它填充一个内部缓冲区,直到它被填满(或到达一行 - 它实际上取决于缓冲区模式):
writeCharBuffer h_@Handle__{..} !cbuf = do
  -- much code omitted, like buffering
      bbuf'' <- Buffered.flushWriteBuffer haDevice bbuf'
  -- more code omitted, like buffering

那么 flushWriteBuffer 在哪里?定义?它实际上是 stdout 的一部分:
stdout :: Handle
stdout = unsafePerformIO $ do
   setBinaryMode FD.stdout
   enc <- getLocaleEncoding
   mkHandle FD.stdout "<stdout>" WriteHandle True (Just enc)
                nativeNewlineMode{-translate newlines-}
                (Just stdHandleFinalizer) Nothing
stdout :: FD
stdout = stdFD 1

文件描述符( FD )是 BufferedIO 的一个实例:
instance BufferedIO FD where
  -- some code omitted
  flushWriteBuffer  fd buf = writeBuf' fd buf

writeBuf使用 instance GHC.IO.Device.RawIO FD 's write ,最终 leads to :
writeRawBufferPtr loc !fd buf off len
  | isNonBlocking fd = unsafe_write -- unsafe is ok, it can't block
  | otherwise   = do r <- unsafe_fdReady (fdFD fd) 1 0 0
                     if r /= 0
                        then write
                        else do threadWaitWrite (fromIntegral (fdFD fd)); write
  where
    do_write call = fromIntegral `fmap`
                      throwErrnoIfMinus1RetryMayBlock loc call
                        (threadWaitWrite (fromIntegral (fdFD fd)))
    write         = if threaded then safe_write else unsafe_write
    unsafe_write  = do_write (c_write (fdFD fd) (buf `plusPtr` off) len)
    safe_write    = do_write (c_safe_write (fdFD fd) (buf `plusPtr` off) len)

where we can see c_safe_write and c_write, which are usually bindings to C library functions:

foreign import capi unsafe "HsBase.h write"
   c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize

所以,putChar使用 write .至少在 GHC 的实现中。然而,该报告不需要该实现,因此允许另一个编译器/运行时使用其他功能。

TL;博士

GHC 的实现使用 write 使用内部缓冲区来写入内容,包括单个字符。

关于Haskell primPutChar 定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34492110/

相关文章:

java - 扫描仪未将值分配给数组

c - FreeRTOS 在调度程序启动之前(或停止之后)排队等待 IO

c++ - 为什么不认为类在静态数据成员初始值设定项中已完全定义?

c++ - 此代码是否有效的 C++?

haskell - Haskell中的身份功能有多个居民?

haskell - 从函数的类型确定函数的行为

haskell - 也许是动态调度、智能构造函数、Template Haskell?

functional-programming - Haskell 函数定义语法

django - 如何处理 mod_wsgi/django 中的阻塞 IO?

c - 位声明 - 对 'variable' 的 undefined reference