【问题标题】:Simple program using Pipes hangs使用 Pipes 的简单程序挂起
【发布时间】:2013-06-30 01:06:24
【问题描述】:

我有以下程序,它在使用runhaskell Toy.hs 运行时不产生任何输出,而是无限期挂起。据我了解,程序应该打印“hi”然后退出。我将不胜感激有关如何调试此类问题的答案和/或建议。我正在使用来自 github (github.com/Gabriel439/Haskell-Pipes-Library) 的 Pipes 4.0.0。

module Toy where

import Pipes
import Control.Monad.State

type Request = String
type Response = String

serveChoice :: Request -> Server Request Response IO ()
serveChoice = forever go
  where go req = do
        lift $ putStrLn req
        respond req

run :: Monad m => () -> Client Request Response (StateT Int m) ()
run () = do
    request "hi"
    return ()

main :: IO ()
main = evalStateT (runEffect $ hoist lift . serveChoice >-> run $ ()) 0

【问题讨论】:

    标签: haskell haskell-pipes


    【解决方案1】:

    你需要使用foreverK而不是forever,像这样:

    module Toy where
    
    import Pipes
    import Pipes.Prelude (foreverK)
    import Control.Monad.State
    
    type Request = String
    type Response = String
    
    serveChoice :: Request -> Server Request Response IO ()
    serveChoice = foreverK go
      where go req = do
            lift $ putStrLn req
            respond req
    
    run :: Monad m => () -> Client Request Response (StateT Int m) ()
    run () = do
        request "hi"
        return ()
    
    main :: IO ()
    main = evalStateT (runEffect $ hoist lift . serveChoice >-> run $ ()) 0
    

    原始版本挂起的原因是您在Reader monad(即((->) a) monad)中使用了forever,而不是管道monad。在这个 monad 中,forever 等价于

    -- i.e.        m b  ->     m c
    forever :: (a -> b) -> (a -> c)
    forever m = m >> forever m
              = m >>= \_ -> forever m
              = \a -> (\_ -> forever m) (m a) a
              = \a -> forever m a
              = forever m
    

    foreverK 可能是您想要的,因为它与pipes-3.3.0 教程中介绍的Servers 相同。

    此更改修复了现在正常完成的程序:

    >>> main
    hi
    >>>
    

    【讨论】:

    • Reader monad 在哪里出现,因为我从未明确调用过它?是否在 Pipes 内部使用?
    • @ajp 这种行为根本不是pipes 特有的。编译器通过调用forever 的上下文推断要使用哪个monad。你不小心使用了forever go,编译器期望的是Request ->类型的函数,而不是管道,所以编译器推断你的意思是Request -> monad,而不是你想要的Server Request Response IO monad。
    猜你喜欢
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    相关资源
    最近更新 更多