了解流媒体库中的类型
Understanding types in the streaming libarary
关于 streaming
库 Stream (Of a) m r
中的 m
是什么?我怎么能从文档中弄清楚这一点 (抱歉,这里是菜鸟)?
我想了解该类型的含义,以便我可以在使用 servant 创建请求流并尝试像这样使用它时解决我的具体问题:
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
但我收到以下错误:
• 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 ()
如果单独给出,Stream (Of a) m r
中的 m
可以是任何类型。
考虑模块中的特定功能时,请注意类型约束。例如,yield
函数具有以下类型:
yield :: Monad m => a -> Stream (Of a) m ()
这里,m
被限制为 Monad
实例的任何类型。这可能是 IO
、[]
(列表)、Maybe
、State
、Reader
等
另一个函数具有这种类型:
stdinLn :: MonadIO m => Stream (Of String) m ()
这里,m
被限制为 MonadIO
实例的任何类型。 MonadIO
类型 class 是 Monad
的子 class,在某种意义上,要使类型成为 MonadIO
,它必须已经是 Monad
.
AFAICT,IO
也是 MonadIO
,但是例如Maybe
不是。
因此,模块中的某些功能比其他功能受到更多限制。 yield
函数比 stdinLn
函数受到的限制更少。您可以将 Maybe
作为 m
与 yield
一起使用,但不能与 stdinLn
.
一起使用
关于您的具体问题,OP 中没有足够的信息进行重现,但看起来 main
使用了 Streaming.Prelude
中的 map
函数:
map :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
此处,m
必须是 Monad
实例。在 Haskell 中,main
函数必须具有类型 IO ()
,因此当使用 do
表示法时,Monad
实例被推断为 IO
.错误消息表明编译器期望 m
为 IO
.
关于 streaming
库 Stream (Of a) m r
中的 m
是什么?我怎么能从文档中弄清楚这一点 (抱歉,这里是菜鸟)?
我想了解该类型的含义,以便我可以在使用 servant 创建请求流并尝试像这样使用它时解决我的具体问题:
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
但我收到以下错误:
• 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 ()
如果单独给出,Stream (Of a) m r
中的 m
可以是任何类型。
考虑模块中的特定功能时,请注意类型约束。例如,yield
函数具有以下类型:
yield :: Monad m => a -> Stream (Of a) m ()
这里,m
被限制为 Monad
实例的任何类型。这可能是 IO
、[]
(列表)、Maybe
、State
、Reader
等
另一个函数具有这种类型:
stdinLn :: MonadIO m => Stream (Of String) m ()
这里,m
被限制为 MonadIO
实例的任何类型。 MonadIO
类型 class 是 Monad
的子 class,在某种意义上,要使类型成为 MonadIO
,它必须已经是 Monad
.
AFAICT,IO
也是 MonadIO
,但是例如Maybe
不是。
因此,模块中的某些功能比其他功能受到更多限制。 yield
函数比 stdinLn
函数受到的限制更少。您可以将 Maybe
作为 m
与 yield
一起使用,但不能与 stdinLn
.
关于您的具体问题,OP 中没有足够的信息进行重现,但看起来 main
使用了 Streaming.Prelude
中的 map
函数:
map :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
此处,m
必须是 Monad
实例。在 Haskell 中,main
函数必须具有类型 IO ()
,因此当使用 do
表示法时,Monad
实例被推断为 IO
.错误消息表明编译器期望 m
为 IO
.