我需要组建一个消费者和一个管道,以便消费者的输出能够输入管道的输入。
我想这可以用这样的组合器来解决:
Consumer i m r -> (r -> Producer o m r') -> Pipe i o m r'
或者这个:
Consumer i m i' -> Pipe i' o m r -> Pipe i o m r
或类似以下的提升功能:
Consumer i m r -> Pipe i o m r
或者像这样:
Consumer i m o -> Pipe i o m r
我尝试consumer >~ pipe
没有成功。那么如何处理呢?
答案 0 :(得分:5)
对于您的第一个类型签名,如果您的Consumer
和Producer
使用多态类型同义词Consumer'
和Producer'
,那么您想要的组合符为(>>=)
:
(>>=) :: Pipe i o m r -> (r -> Pipe i o m r') -> Pipe i o m r'
Consumer' i m r
将类型检查为Pipe i o m r
。同样,Producer' o m r'
会将Pipe i o m r'
类型检查。
答案 1 :(得分:4)
类似于您的签名Consumer i m o -> Pipe i o m r
的内容可以这样做:
{-# LANGUAGE RankNTypes #-}
import Pipes
foo :: Monad m => Consumer' i m o -> Pipe i o m ()
foo consumer = consumer >>= yield
我使用了Consumer'
多态类型的同义词,因为它并非真正关闭"下游",它可以用作Pipe
从未实际yield
}秒。为了使它产生消费者的回报值,我们只使用monadic bind。
至于你的Consumer i m r -> Pipe i o m r
签名,它只是使用多态类型同义词的身份:
iden :: Monad m => Consumer' i m r -> Pipe i o m r
iden consumer = consumer