假设我有一个函数(plusOne在下面的示例中),它只接受并返回一个Int. 但我没有Int; 相反,我有一个Maybe Int; 如果这Maybe Int包含一个值,那么我想将它传递给plusOne并获得一个返回值,Just或者plusOne如果它是一个值,Nothing那么我希望它Nothing传播。
在这种情况下,我们必须liftM以一种优雅的方式编写代码:
import Control.Monad
plusOne :: Int -> Int
plusOne n =
n+1 -- a very complicated computation that is failsafe
main =
let n = Just 15 -- a very complicated computation that can fail
in let res = liftM plusOne n
in print res
到现在为止还挺好。但是,这样的事情也可以用构造函数来完成吗?
忘了plusOne。现在我有:data SomeData = SomeData Int并且想Maybe (SomeData Int)从我的Maybe Int. 该解决方案似乎明显不那么优雅:
import Control.Monad
data SomeData = SomeData Int
deriving Show -- so that print works
main =
let n = Just 15
in let res = n >>= (\nn -> Just (SomeData nn))
-- alternatively: in let res = liftM (\nn -> SomeData nn) n
in print res
上述两种解决方案(with>>=或 with liftM)都需要通过一个匿名 lambda 函数,根据我的直觉,这不是必需的,只会破坏代码。有没有办法避免它?我可以以某种方式“提升”someData构造函数,就像我可以plusOne在第一个片段中提升一样吗?