Search code examples
haskellfunctional-programminghaskell-platformoption-type

Haskell Monad equivalent


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)

Solution

  • 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.