我一直在阅读 John Hughes 的 Programming with Arrows,我得到了第一个练习,他要求读者为箭头实现一个通用的过滤器函数 filterA。规范说它应该像过滤 (->) 箭头和 filterM 过滤 Kliesli 箭头一样。我尝试按如下方式实现它,但我最终得到的结果似乎比我在网上看到的其他解决方案示例要简单一些。我担心我错过了一些东西,但我的答案似乎符合规范的建议。它匹配 filter for -> 和 filterM for Kliesli 箭头。对于流函数,它也以合理的方式工作。
listcase [] = Left ()
listcase (x:xs) = Right (x,xs)
filterA :: forall a arr. ArrowChoice arr => arr a Bool -> arr [a] [a]
filterA f = arr listcase >>>
arr (const []) ||| (switchA *** filterA f >>> arr (uncurry (++)))
where switchA :: ArrowChoice arr => arr a [a]
switchA = (f &&& id) >>> arr (\(b,x) -> if b then [x] else [])
Run Code Online (Sandbox Code Playgroud)
这是一个可以接受的实现吗?
我似乎可以接受。作为替代方案,您可以考虑使用uncurry ($)和
switchA :: ArrowChoice arr =>> arr a ([a] -> [a])
switchA = (f &&& arr id) >>> arr test
where
test (False, _) = id
test (True, x) = (x :)
Run Code Online (Sandbox Code Playgroud)