比方说,我有以下类型:
type LinkID = Int
data Link = Link {
lid :: LinkID,
llength :: Int
}
data Snap = Snap {
slid :: LinkID,
slength :: Int
}
现在,我想编写一个基于管道的函数来执行此操作:
getSnaps :: LinkID -> [Link] -> [Snap] -> [(LinkID, [Snap])]
getSnaps l lks snp = map (\x -> (lid x, filter (\y -> lid x == slid y) snp)) a
where a = filter (\x -> lid x > l) lks
假设我已经拥有了 Link
和 Snap
的制作人,我怎样才能从这两个制作人的管道世界中实现上述 getSnaps
功能:
psnap :: Producer Snap IO ()
psnap = undefined
plink :: Producer Link IO ()
plink = undefined
psnap
和 plink
的实际类型更复杂(通过使用attoparsec-pipes创建),但我想知道如何从 psnap
和 plink
实现getSnaps的功能 . 有没有正确的方法来解决这类问题?
1 回答
我提出的解决方案与您的代码非常相似 . 我刚用
Pipes.Prelude.map
替换map
,用Pipes.Prelude.filter
替换了其中一个过滤器:请注意,有一个非平凡的部分,即上述解决方案严格地将
snp
Producer
的内容加载到列表snp'
中 . 原因是我们必须重复使用列表的内容,因此我们需要将整个列表缓存在内存中以便重复使用 .