gpt4 book ai didi

haskell - 如何检测 Haskell Pipe 中的最后一个 block ?

转载 作者:行者123 更新时间:2023-12-04 08:42:23 25 4
gpt4 key购买 nike

我有一个小 Haskell Pipe打印出它运行了多少次:

counterPipe :: Pipe String String IO r
counterPipe = go 0
where
go n = do
await >>= yield
let n' = succ n
liftIO $ putStrLn $ "Chunk " ++ show n'
go n'

一旦处理完最后一个 block ,我希望能够打印出一条消息,并可能执行其他任务。我该怎么做呢?

最佳答案

我可以通过更改 counterPipe 来实现此功能的输入类型为 Maybe String并注入(inject)一个额外的Nothing上游管道完成后:

import Pipes
import Pipes.Core (respond)
import Control.Applicative ((<*))

withEOF :: (Monad m) => Proxy a' a b' b m r -> Proxy a' a b' (Maybe b) m r
withEOF p = for p (respond . Just) <* respond Nothing

counterPipe :: Pipe (Maybe String) String IO Int
counterPipe = go 0
where
go n = do
mx <- await

case mx of
Just x -> do
yield x
let n' = succ n
liftIO $ putStrLn $ "Chunk " ++ show n'
go n'
Nothing -> do
return n

finishCounter :: Int -> Pipe a b IO ()
finishCounter n = liftIO $ putStrLn $ unwords ["Finished after", show n, "chunks"]

示例驱动程序:
import qualified Pipes.Prelude as P
main = runEffect $ withEOF P.stdinLn >-> (counterPipe >>= finishCounter) >-> P.stdoutLn

我认为这种模式应该可以抽象成类似的东西
whileJust :: (Monad m) => Proxy a' a b' b m r -> Proxy a' (Maybe a) b' b m (Maybe r)

所以你可以写
withEOF P.stdinLn >-> (whileJust counterPipe >>= maybe (return ()) finishCounter) >-> P.stdoutLn

无需更改您原来的 counterPipe定义;
但我从未使用过 Pipes之前(上面的解决方案是通过查看类型和玩 type-domino 来解决的),所以我没有设法写 whileJust (签名可能太通用了,我无法弄清楚)。

关于haskell - 如何检测 Haskell Pipe 中的最后一个 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34257148/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com