假设我有一个函数(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
在第一个片段中提升一样吗?