From 60eb7dc37c1d5e473a153020e9513d6c968b6cad Mon Sep 17 00:00:00 2001 From: Abhijit Sarkar Date: Tue, 2 Jan 2024 16:23:02 -0800 Subject: [PATCH] Update problem 79 --- ninety-nine-haskell.cabal | 1 + package.yaml | 1 + src/Monads.hs | 23 +++++++++++++---------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ninety-nine-haskell.cabal b/ninety-nine-haskell.cabal index 89dee03..faef771 100644 --- a/ninety-nine-haskell.cabal +++ b/ninety-nine-haskell.cabal @@ -54,6 +54,7 @@ library , psqueues , random , split + , transformers , vector default-language: Haskell2010 diff --git a/package.yaml b/package.yaml index d1ac887..61ec264 100644 --- a/package.yaml +++ b/package.yaml @@ -53,6 +53,7 @@ library: - random - array - mtl + - transformers - psqueues - hashable - vector diff --git a/src/Monads.hs b/src/Monads.hs index c25e231..8bf7011 100644 --- a/src/Monads.hs +++ b/src/Monads.hs @@ -1,5 +1,4 @@ {-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE FlexibleContexts #-} module Monads ( Operator (..), @@ -13,9 +12,10 @@ where import qualified Control.Monad as M import Control.Monad.State (StateT) import qualified Control.Monad.State as S +import Control.Monad.Trans.Maybe (MaybeT) +import qualified Control.Monad.Trans.Maybe as MbT import Control.Monad.Writer (Writer) import qualified Control.Monad.Writer as W -import qualified Data.Maybe as Mb import Data.Monoid (Sum (..)) import qualified Data.Monoid as Md @@ -151,22 +151,25 @@ data Element = Operator Operator | Operand Integer deriving stock (Show, Eq) type Stack = [Integer] -type Logger = Writer [(Stack, Maybe Operator)] +type Logs = [(Stack, Maybe Operator)] type Result = Maybe Integer +type Calculation = MaybeT (StateT Stack (Writer Logs)) Integer + calculatePostfix :: [Element] -> (Result, [(Stack, Maybe Operator)]) calculatePostfix xs = (res, logs) where - ((res, _), logs) = W.runWriter $ S.runStateT (calc xs) [] + ((res, _), logs) = W.runWriter $ S.runStateT (MbT.runMaybeT (calc xs)) [] -calc :: [Element] -> StateT Stack Logger Result -calc [] = S.gets result -calc (Operand n : xs) = S.get >>= loop xs Nothing . (n :) -calc (Operator op : xs) = - S.get >>= Mb.maybe (return Nothing) (loop xs (Just op)) . runOp op +calc :: [Element] -> Calculation +calc elems = + S.get >>= case elems of + [] -> result + (Operand n : xs) -> loop xs Nothing . (n :) + (Operator op : xs) -> runOp op M.>=> loop xs (Just op) -loop :: [Element] -> Maybe Operator -> Stack -> StateT Stack Logger Result +loop :: [Element] -> Maybe Operator -> Stack -> Calculation loop xs op s = W.tell [(s, op)] >> S.put s >> calc xs result :: (MonadFail m) => Stack -> m Integer