Luc*_*cky 0 haskell functional-programming haskell-platform maybe
如果我们选择它们,两个函数是否等效monadPlusSDif,Maybe作为数据类型MonadPlus?
tdif :: Int -> Int -> Maybe Int
tdif x y
| y == 0 = Nothing
| otherwise = Just (div x y)
monadPlusSDif :: MonadPlus m => Int -> Int -> m Int
monadPlusSDif x y = guard (y /= 0) >> return (div x y)
Run Code Online (Sandbox Code Playgroud)
那么,对于Maybe该MonadPlus实例
instance MonadPlus Maybe where
mempty = Nothing
Run Code Online (Sandbox Code Playgroud)
并guard实现为
guard b = if b then return () else mempty
-- = if b then Just () else Nothing
Run Code Online (Sandbox Code Playgroud)
有了这些知识,您可以用等式推理来推断,当m是Maybe,你可以替换原来的代码
monadPlusSDif x y = guard (y /= 0) >> return (div x y)
Run Code Online (Sandbox Code Playgroud)
同
monadPlusSDif x y = (if y /= 0
then Just ()
else Nothing) >> Just (div x y)
Run Code Online (Sandbox Code Playgroud)
要么
monadPlusSDif x y
| y /= 0 = Just () >>= \_ -> Just (div x y)
| otherwise = Nothing >>= \_ -> Just (div x y)
Run Code Online (Sandbox Code Playgroud)
要么
monadPlusSDif x y
| y /= 0 = Just (div x y)
| otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)
要么
monadPlusSDif x y
| y == 0 = Nothing
| otherwise = Just (div x y)
Run Code Online (Sandbox Code Playgroud)
所以你看到功能是相同的.
如果这些函数具有相同的行为m ~ Maybe,但它们的编译字节代码表示可能会有所不同.你也可以用普通MonadPlusmonad的实际防护来实现它
monadPlusSDif :: MonadPlus m => Int -> Int -> m Int
monadPlusSDif x y
| y == 0 = mzero
| otherwise = return $ x `div` y
Run Code Online (Sandbox Code Playgroud)
然后你可以用它作为
bigEquation :: Int -> Int -> Maybe Int
bigEquation x y = do
z1 <- monadPlusSDif x y
z2 <- monadPlusSDif (x + y) (x - y)
z3 <- monadPlusSDif y x
return $ z1 + z2 * z3
Run Code Online (Sandbox Code Playgroud)
并且编译器将能够在该上下文中找出它应该Maybe用于m.