2013-06-30 31 views
7

Tôi có chương trình sau, không tạo ra kết quả khi chạy với runhaskell Toy.hs và thay vào đó bị treo vô thời hạn. Theo sự hiểu biết của tôi, chương trình nên in "hi" và sau đó thoát ra. Tôi sẽ đánh giá cao một câu trả lời và/hoặc tư vấn về cách gỡ lỗi một vấn đề như vậy. Tôi đang sử dụng Pipes 4.0.0 của github (github.com/Gabriel439/Haskell-Pipes-Library).Chương trình đơn giản sử dụng Ống treo

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 

Trả lời

9

Bạn cần phải sử dụng foreverK thay vì forever, như thế này:

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 

Lý do phiên bản ban đầu của bạn bị treo là bạn sử dụng forever trong Reader đơn nguyên (tức là ((->) a) đơn nguyên) và không phải là ống đơn. Trong đơn nguyên này, forever tương đương với :

-- 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 có lẽ là những gì bạn muốn, vì nó là thành ngữ tương tự cho Server s giới thiệu trong pipes-3.3.0 hướng dẫn.

thay đổi này sửa chữa các chương trình mà hiện nay hoàn bình thường:

>>> main 
hi 
>>> 
+0

đâu các đơn nguyên đọc đi vào hình ảnh, như tôi đã không bao giờ gọi nó một cách rõ ràng? Nó được sử dụng trong nội bộ trong Pipes? – ajp

+4

@ajp Hành vi này không phải là 'đặc trưng 'của tất cả. Trình biên dịch infers mà monad để sử dụng bởi bối cảnh mà bạn gọi là 'forever'. Bạn vô tình sử dụng 'forever go', nơi trình biên dịch mong đợi một hàm kiểu' Request -> ', không phải là một đường ống, do đó trình biên dịch suy ra rằng đơn nguyên bạn có nghĩa là' Request -> 'monad chứ không phải« Server Request Response IO' monad như bạn dự định. –

Các vấn đề liên quan