在 Haskell 中将一个函子映射到另一个函子
Mapping a functor to another in Haskell
我有一个生成 Maybe a
类型的函数,我在函数中使用它来生成 Either 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
替换,但问题是我不确定如何 'map' Nothing
到 Left NoSpace
fmap
调用甚至提取此模式以创建我自己的 util 函数。
您正在查找 maybe
函数:
cvX ... =
...
maybe (Left NoSpace) (\p -> Right (x2:x1:(fromJust (rmX (-1) p)))) $
rmX 1 xs
在这种情况下,值得一提的是 errors package. It offers a number of functions for juggling Maybe
, Either
and related types, including note
,它“[标记] Maybe
的 Nothing
值”:
note :: a -> Maybe b -> Either a b
cvX ... =
...
note NoSpace $ fmap (\p -> x2:x1:(fromJust (rmX (-1) p))) (rmX 1 xs)
不出所料,note
的实现使用 maybe
与 Sebastian Redl 的答案完全一样。
P.S.: 使用 fromJust
总是有点不愉快,因为它在给定 Nothing
时会失败。如果 rmX (-1)
无法生成 Nothing
,您可能需要考虑分解出一个单独的函数,该函数不使用 return Maybe a
来代替 fromJust (rmX (-1) p)
。
一个类似的选择是使用 Maybe
monad 直到最后,然后根据需要应用 Left
或 Right
maybe
.
maybe (Left NoSpace) Right $ do
p1 <- rmX 1 xs
p2 <- rmX (-1) p1
return (x2:x1:p2)
这里有很大的调整空间,具体取决于您对 do
表示法与 >>=
的偏好:
-- 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
我有一个生成 Maybe a
类型的函数,我在函数中使用它来生成 Either 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
替换,但问题是我不确定如何 'map' Nothing
到 Left NoSpace
fmap
调用甚至提取此模式以创建我自己的 util 函数。
您正在查找 maybe
函数:
cvX ... =
...
maybe (Left NoSpace) (\p -> Right (x2:x1:(fromJust (rmX (-1) p)))) $
rmX 1 xs
在这种情况下,值得一提的是 errors package. It offers a number of functions for juggling Maybe
, Either
and related types, including note
,它“[标记] Maybe
的 Nothing
值”:
note :: a -> Maybe b -> Either a b
cvX ... =
...
note NoSpace $ fmap (\p -> x2:x1:(fromJust (rmX (-1) p))) (rmX 1 xs)
不出所料,note
的实现使用 maybe
与 Sebastian Redl 的答案完全一样。
P.S.: 使用 fromJust
总是有点不愉快,因为它在给定 Nothing
时会失败。如果 rmX (-1)
无法生成 Nothing
,您可能需要考虑分解出一个单独的函数,该函数不使用 return Maybe a
来代替 fromJust (rmX (-1) p)
。
一个类似的选择是使用 Maybe
monad 直到最后,然后根据需要应用 Left
或 Right
maybe
.
maybe (Left NoSpace) Right $ do
p1 <- rmX 1 xs
p2 <- rmX (-1) p1
return (x2:x1:p2)
这里有很大的调整空间,具体取决于您对 do
表示法与 >>=
的偏好:
-- 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