5

我一直在阅读 John Hughes 的 Programming with Arrows,我开始了第一个练习,他要求读者为箭头实现一个通用的过滤器函数 filterA。规范说它应该表现得像过滤 (->) 箭头和 filterM 过滤 Kliesli 箭头。我尝试按如下方式实现它,但我最终得到的结果似乎比我在网上看到的其他解决方案示例要简单一些。我担心我错过了一些东西,但我的答案似乎按照规范的建议工作。它匹配 -> 的过滤器和 Kliesli 箭头的 filterM。它也以合理的方式适用于流函数。

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 [])

这是一个可接受的实现吗?

4

1 回答 1

4

这对我来说似乎可以接受。作为替代方案,您可以考虑使用uncurry ($)

switchA :: ArrowChoice arr =>> arr a ([a] -> [a])
switchA = (f &&& arr id) >>> arr test
  where
    test (False, _) = id
    test (True, x)  = (x :)
于 2013-04-15T14:24:07.450 回答