From 8d9529d7c6d28f62e4642742044bddc51f74e34a Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Tue, 3 Mar 2026 13:54:41 -0800 Subject: [PATCH] lab08: impl --- lab08/monadLab.lhs | 50 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/lab08/monadLab.lhs b/lab08/monadLab.lhs index 56e3a87..9845f28 100644 --- a/lab08/monadLab.lhs +++ b/lab08/monadLab.lhs @@ -32,12 +32,19 @@ but without the do syntax. Implement Times and Divide. Try the Times case without monads (as we did with 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. 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. @@ -53,9 +60,20 @@ The Plus case is done for you once again. Be sure to check for zero with Divide > i <- mi > j <- mj > return $ i + j -> applyOp' Minus mi mj = error "TBD" -> applyOp' Times mi mj = error "TBD" -> applyOp' Divide mi mj = error "TBD" +> applyOp' Minus mi mj = do +> i <- mi +> 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: @@ -75,6 +93,28 @@ Experiment with these functions and the >>= syntax. Here is one example: > 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? +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'