Haskell Monad相当于

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)

Chr*_*lor 9

那么,对于MaybeMonadPlus实例

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)

有了这些知识,您可以用等式推理来推断,当mMaybe,你可以替换原来的代码

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)

所以你看到功能是相同的.


bhe*_*ilr 5

如果这些函数具有相同的行为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.