在Haskell中将函子映射到另一函子

在Haskell中将函子映射到另一函子,haskell,functor,Haskell,Functor,我有一个生成的函数,可能是a类型,我在一个函数中使用它来生成或是b a。是否有一种方法可以将Nothing映射到Left x以简化代码?以下代码提供了一些上下文: rmX :: ... -> Maybe a cvX :: ... -> Either CVXError a data CVXError = BadIndex | NoCover | NoSpace cvX ... = ... case rmx 1 xs of Nothing -> Left NoSpa

我有一个生成
的函数,可能是a
类型,我在一个函数中使用它来生成
或是b a
。是否有一种方法可以将
Nothing
映射到
Left x
以简化代码?以下代码提供了一些上下文:

rmX :: ... -> Maybe a
cvX :: ... -> Either CVXError a
data CVXError = BadIndex | NoCover | NoSpace
cvX ... =
  ...
  case rmx 1 xs of
    Nothing -> Left NoSpace
    Just p  -> Right (x2:x1:(fromJust (rmX (-1) p)))
-- given that rmX always passes on negative value arg
case语句只是请求用
fmap
替换,但问题是我不确定如何在
fmap
调用中将
映射到
左NoSpace
,或者甚至提取此模式以生成我自己的util函数。

您正在寻找函数:

cvX ... =
  ...
  maybe (Left NoSpace) (\p -> Right (x2:x1:(fromJust (rmX (-1) p)))) $
    rmX 1 xs

在这方面,值得一提的是一揽子计划。它提供了许多杂耍
Maybe
和相关类型的功能,包括“[标记]a
Maybe
无值”:

不出所料,
note
的实现使用了
maybe
,与Sebastian Redl的答案完全相同


附言:从just
开始使用
总是有点令人不快,因为它在没有任何东西的情况下是如何失败的。如果<代码> RMX(- 1)< /代码>不能产生<代码>任何< <代码>,您可能需要考虑一个单独的函数,该函数不返回<代码>可能是一个< /代码>,而不是<代码>从(RMX(-1)p)< /代码> .< /P> < P> >一个类似的选项是使用<代码>可能单元格,直到最后,然后根据需要使用
可能
应用
左侧
右侧

maybe (Left NoSpace) Right $ do
     p1 <- rmX 1 xs
     p2 <- rmX (-1) p1
     return (x2:x1:p2)
cvX ... =
  ...
  note NoSpace $ fmap (\p -> x2:x1:(fromJust (rmX (-1) p))) (rmX 1 xs)
maybe (Left NoSpace) Right $ do
     p1 <- rmX 1 xs
     p2 <- rmX (-1) p1
     return (x2:x1:p2)
-- untested; take these with a grain of salt...

maybe (Left NoSpace) Right $ do
    p <- rmX 1 xs >>= rmX (-1) 
    return (x2:x1:p)

maybe (Left NoSpace) Right (rmX 1 xs >>= rmX (-1) >>= (return . (x1:)) >>= (return . (x2:)))

-- etc