了解流式图书馆中的类型

zor*_*119 5 monads streaming haskell

在问候的streaminglibarary什么是mStream (Of a) m r?我怎么能从文档中弄清楚这一点(抱歉,这里有一个菜鸟)

我想了解这种类型的含义,以便我可以解决我使用s​​ervant创建请求流的特定问题,同时尝试使用它:

post :: Maybe Int -> ClientM [BlogPost]
post = ...

stream :: Stream (Of (ClientM [BlogPost])) ClientM ()
stream = S.map posts $ S.each $ [Just p | p <- [1..5]]

main = do
  let url = ...
  S.print $ S.map (\x -> runClientM x url) stream
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

• Couldn't match type ‘ClientM’ with ‘IO’
  Expected type: S.Stream (S.Of (ClientM [BlogPost])) IO ()
    Actual type: S.Stream (S.Of (ClientM [BlogPost])) ClientM ()
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 7

如果单独给出,则min Stream (Of a) m r可以是任何类型.

在考虑模块中的特定功能时,请注意类型约束.例如,该yield函数具有以下类型:

yield :: Monad m => a -> Stream (Of a) m ()
Run Code Online (Sandbox Code Playgroud)

这里,m被约束为任何类型的Monad实例.这可能是IO,[](名单)Maybe,State,Reader,等.

另一个函数有这种类型:

stdinLn :: MonadIO m => Stream (Of String) m ()
Run Code Online (Sandbox Code Playgroud)

这里,m被约束为任何类型的MonadIO实例.该MonadIO类型类的子类Monad,在这个意义上,对于一个类型是MonadIO,它必须已经是Monad.

AFAICT IO也是一个MonadIO,但是例如Maybe不是.

因此,模块中的某些功能比其他功能更受限制.该yield函数比stdinLn函数的约束更少.您可以使用Maybe作为myield,但不是stdinLn.

关于你的具体问题,OP中没有足够的信息用于repro,但它看起来像main使用以下map函数Streaming.Prelude:

map :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
Run Code Online (Sandbox Code Playgroud)

在这里,m必须是一个Monad实例.在Haskell中,main函数必须具有类型IO (),因此在使用do表示法时,Monad实例被推断为IO.错误消息指出编译器期望m的是IO.

  • 有趣的是:根据惯例,名为`m`的类型变量几乎总是代表一个monad(和`f`一些其他类型的functor). (2认同)