我已经简化了我需要的一些代码的类型签名,它看起来大致如下:
Functor f => f (Maybe a, b) -> (Maybe (f a), f b)
Run Code Online (Sandbox Code Playgroud)
我可以,我该如何实现这样的功能?如果是这样,怎么样?我猜想我需要将仿函数推向使用Traversable,但是我无法将这一切都放在我脑海中.
f向下推一级可以通过以下方式完成:
fn :: Functor f => f (a, b) -> (f a, f b)
fn v = (fmap fst v, fmap snd v)
Run Code Online (Sandbox Code Playgroud)
(请注意,如果你想元组是不可遍历两个方面.)
第二部分是
Functor f => f (Maybe a) -> Maybe (f a)
Run Code Online (Sandbox Code Playgroud)
这种类型只有居住者const Nothing,因为你可以应用于这个值的唯一函数是fmap,获得f b某些类型的值b.
为了说明为什么这第二部分是不可能的,考虑的是,IO是的一个实例Functor.如果您可以Maybe (IO a)从您的值中获取,则应用isJust它将泄漏有关原始IO (Maybe a)值的一些信息而不执行它.