lab08: impl

This commit is contained in:
2026-03-03 13:54:41 -08:00
parent 70c88a8ba2
commit 8d9529d7c6

View File

@@ -32,12 +32,19 @@ but without the do syntax.
Implement Times and Divide. Try the Times case without monads (as we did with Implement Times and Divide. Try the Times case without monads (as we did with
the Plus case). the Plus case).
> applyOp Times mi mj = error "TBD" > applyOp Times mi mj =
> case mi of
> Nothing -> Nothing
> Just i ->
> case mj of
> Nothing -> Nothing
> Just j -> Just $ i * j
For the Divide case, use bind (>>=) as we did for Minus. For the Divide case, use bind (>>=) as we did for Minus.
On an attempt to divide by 0, return Nothing as the answer. On an attempt to divide by 0, return Nothing as the answer.
> applyOp Divide mi mj = error "TBD" > applyOp Divide mi mj =
> mi >>= (\i -> mj >>= (\j -> if j == 0 then Nothing else Just $ i `div` j))
The following test cases will help you verify your changes. The following test cases will help you verify your changes.
@@ -53,9 +60,20 @@ The Plus case is done for you once again. Be sure to check for zero with Divide
> i <- mi > i <- mi
> j <- mj > j <- mj
> return $ i + j > return $ i + j
> applyOp' Minus mi mj = error "TBD" > applyOp' Minus mi mj = do
> applyOp' Times mi mj = error "TBD" > i <- mi
> applyOp' Divide mi mj = error "TBD" > j <- mj
> return $ i - j
> applyOp' Times mi mj = do
> i <- mi
> j <- mj
> return $ i * j
> applyOp' Divide mi mj = do
> i <- mi
> j <- mj
> if j == 0
> then Nothing
> else return $ i `div` j
More test cases: More test cases:
@@ -75,6 +93,28 @@ Experiment with these functions and the >>= syntax.
Here is one example: Here is one example:
> testIncDec = Just 7 >>= mincr >>= mincr >>= mincr >>= mdecr > testIncDec = Just 7 >>= mincr >>= mincr >>= mincr >>= mdecr
> testIncDec' = do
> i <- Just 7
> i <- mincr i
> i <- mincr i
> i <- mincr i
> i <- mdecr i
> return i
Does bind seem more natural in this case than using do? Why or why not? Does bind seem more natural in this case than using do? Why or why not?
The bind behaves sort of like an upgraded pipe `|` from shell,
where the output of one function is piped into the next function,
but with the added benefit of error handling
The do syntax is a bit more explicit in this case, as it requires unwrapping the value,
performing the operation, and then wrapping the value back up
> main :: IO ()
> main = do
> print testapp1
> print testapp2
> print testapp1'
> print testapp2'
> print testIncDec
> print testIncDec'