문제

Are both functions equivalent if we choose them at monadPlusSDif, Maybe as the data type for 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)
도움이 되었습니까?

해결책 2

These functions will have equivalent behavior if m ~ Maybe, but their compiled byte-code representation will likely be different. You could also implement it with actual guards for general MonadPlus monads as

monadPlusSDif :: MonadPlus m => Int -> Int -> m Int
monadPlusSDif x y
    | y == 0 = mzero
    | otherwise = return $ x `div` y

Then you could use it as

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

and the compiler would be able to figure out that in that context, it should use Maybe for m.

다른 팁

Well, for Maybe the MonadPlus instance is

instance MonadPlus Maybe where
  mempty = Nothing

and guard is implemented as

guard b = if b then return () else mempty
--      = if b then Just   () else Nothing

With that knowledge, you can use equational reasoning to deduce that, when m is Maybe, you can replace the original code

monadPlusSDif x y = guard (y /= 0) >> return (div x y)

with

monadPlusSDif x y = (if y /= 0
  then Just ()
  else Nothing) >> Just (div x y)

or

monadPlusSDif x y
  | y /= 0    = Just () >>= \_ -> Just (div x y)
  | otherwise = Nothing >>= \_ -> Just (div x y)

or

monadPlusSDif x y
  | y /= 0    = Just (div x y)
  | otherwise = Nothing

or

monadPlusSDif x y
  | y == 0    = Nothing
  | otherwise = Just (div x y)

so you see that the functions are identical.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top