【问题标题】:Convert FD to Handle将 FD 转换为句柄
【发布时间】:2013-12-16 14:18:01
【问题描述】:

我想打开一个伪 tty 并使用生成的从终端连接到子进程上的标准输入/标准输出。 openPseudoTerminal 给了我一个IO (System.Posix.Types.Fd, System.Posix.Types.Fd),我试图在GHC.IO.Handle.Fd 中使用fdToHandle 将其转换为一对句柄(GHC 特定,但我找不到另一个这样的函数)。但是,我得到以下信息:

liftA (fdToHandle *** fdToHandle) openPseudoTerminal
Couldn't match type `System.Posix.Types.Fd'
               with `System.Posix.Internals.FD'

任何想法我如何在这两个(大概相似的)事物之间进行转换?

对于奖励积分,这会给我一个IO (IO Handle, IO Handle) - 有没有一种巧妙的方法可以将它转换为IO (Handle, Handle)

【问题讨论】:

    标签: linux haskell tty


    【解决方案1】:

    openPseudoTerminal 在 unix 包中,它还在System.Posix.IO 中提供了具有适当类型的fdToHandle

    我将使用迄今为止我想出的最好的单线来处理 IO Handles 对:

    getHandles :: IO (Handle, Handle)
    getHandles =
      openPseudoTerminal >>= uncurry ap . (fmap (,) . fdToHandle *** fdToHandle)
    

    或:

    getHandles =
      openPseudoTerminal >>= uncurry (ap . fmap (,)) . join (***) fdToHandle
    

    【讨论】:

      【解决方案2】:

      您可以向 GHCI 询问有关这些类型的信息 --

      >> :i FD
      type FD = Foreign.C.Types.CInt
      >> :i Fd
      newtype Fd = Fd Foreign.C.Types.CInt
      

      所以它们本质上是相同的,除了一个是newtype,另一个是type。所以转换函数是(我建议选择更好的名字)

      convert :: FD -> Fd
      convert = Fd
      
      convert' :: Fd -> FD
      convert' (Fd x) = x
      

      关于从 IO (IO Handle, IO Handle) 转换为 IO (Handle,Handle) 的问题,您可以明确地这样做

      flatten :: IO (IO a, IO a) -> IO (a,a)
      flatten x = do
        (a,b) <- x
        a'    <- a
        b'    <- b
        return (a', b')
      

      但更好的方法是首先避免创建IO (IO Handle, IO Handle)。因为你的类型是

      openPseudoTerminal :: IO (Fd, Fd)
      fdToHandle         :: FD -> IO Handle
      

      你可以的

      getHandles :: IO (Handle, Handle)
      getHandles = do
        (Fd a, Fd b) <- openPseudoTerminal
        a'           <- fdToHandle a
        b'           <- fdToHandle b
        return (a', b')
      

      【讨论】:

      • 这两种类型都是NumIntegral的实例,所以你可以使用fromIntegral来回转换。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-06-28
      • 2014-09-18
      • 1970-01-01
      相关资源
      最近更新 更多