Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell-primPutChar定义_Haskell_Io_Definition - Fatal编程技术网

Haskell-primPutChar定义

Haskell-primPutChar定义,haskell,io,definition,Haskell,Io,Definition,我试图弄清楚基本的IOHaskell函数是如何定义的,所以我使用了putChar函数定义: putChar :: Char -> IO () putChar = primPutChar 但是现在,我在任何地方都找不到关于这个primPutChar函数的更多信息。也许它是指一个预编译的函数,从共享对象中以二进制形式提供?如果是这样的话,有可能看到它的源代码吗?什么是prim*意思 既然你是从报告的角度问这个问题,那么让我们也从报告的角度回答这个问题: 在Haskell中无法定

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

putChar    :: Char -> IO ()
putChar    =  primPutChar
但是现在,我在任何地方都找不到关于这个
primPutChar
函数的更多信息。也许它是指一个预编译的函数,从共享对象中以二进制形式提供?如果是这样的话,有可能看到它的源代码吗?

什么是
prim*
意思 既然你是从报告的角度问这个问题,那么让我们也从报告的角度回答这个问题:

在Haskell中无法定义的原语(以“
prim
”开头的名称表示)在模块
PreludeBuiltin
中以系统相关的方式定义,此处未显示

这在中国仍然是一样的

它在GHC中的实现方式 但是,您可以查看它在GHC中的实现方式:

putChar         :: Char -> IO ()
putChar c       =  hPutChar stdout c
从那里你将深入兔子洞。你怎么知道怎么打印东西?嗯,没有。它仅“缓冲”并检查您是否可以写入:

hPutChar :: Handle -> Char -> IO ()
hPutChar handle c = do
    c `seq` return ()
    wantWritableHandle "hPutChar" handle $ \ handle_  -> do
     hPutcBuffered handle_ c
写入是在填充内部缓冲区直到其满(或到达一行,实际上取决于缓冲区模式)的过程中完成的:

文件描述符(
FD
)是以下内容的实例:

writeBuf
使用,最终:

因此,
putChar
使用。至少在GHC的实施中。但是,报告不需要该实现,因此允许另一个编译器/运行时使用其他函数

TL;博士
GHC的实现使用内部缓冲区来写东西,包括单个字符。

函数名以
prim
开头意味着它是一个内置原语。这种函数的定义不能用Haskell来给出;目标平台之间也会有所不同。有时它是一个外部函数,有时它是编译器熟知的函数名(这样它可以在调用函数的地方直接发出适当的代码)。@Andreychernayakhovskiy将您的答案作为答案,而不是注释。您可以在基本包中看到它:由于最新的haddock,您可以非常轻松地导航它@西比:谢谢,真有趣!然而,为什么在那个地方,
putChar
是用Haskell代码定义的,而在onlinereport中,他们暗示这是一个原始函数,正如@AndreyChernyakhovskiy指出的那样?前者是否编译一次,然后放入库中?EDIT@Zeta刚刚用答案打败了我:)
writeCharBuffer h_@Handle__{..} !cbuf = do
  -- much code omitted, like buffering
      bbuf'' <- Buffered.flushWriteBuffer haDevice bbuf'
  -- more code omitted, like buffering
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
instance BufferedIO FD where
  -- some code omitted
  flushWriteBuffer  fd buf = writeBuf' fd buf
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)
foreign import capi unsafe "HsBase.h write"
   c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize