From 05310cc2cb4bb11cbc9fecbd3c15706ca0ebb5ab Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 6 Dec 2024 11:08:39 +0000 Subject: [PATCH] [refactor] pullPorts again, with StateT + mapM (#64) `StateT` captures that we both pass the list of available things into `pull1Port` and then return the reduced version thereof. `mapM` captures that each invocation of `pull1Port` returns a single thing that was pulled, or an error. --- brat/Brat/Checker/Helpers.hs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/brat/Brat/Checker/Helpers.hs b/brat/Brat/Checker/Helpers.hs index 74f0193..39b8ea3 100644 --- a/brat/Brat/Checker/Helpers.hs +++ b/brat/Brat/Checker/Helpers.hs @@ -36,6 +36,7 @@ import Bwd import Hasochism import Util (log2) +import Control.Monad.State.Lazy (StateT(..), runStateT) import Control.Monad.Freer (req) import Data.Bifunctor import Data.Foldable (foldrM) @@ -108,21 +109,18 @@ pullPortsSig :: Show ty -> Checking [(PortName, ty)] pullPortsSig = pullPorts id showSig -pullPorts :: forall a ty. Show ty - => (a -> PortName) -- A way to get a port name for each element +pullPorts :: forall a ty + . (a -> PortName) -- A way to get a port name for each element -> ([(a, ty)] -> String) -- A way to print the list -> [PortName] -- Things to pull to the front -> [(a, ty)] -- The list to rearrange -> Checking [(a, ty)] -pullPorts _ _ [] types = pure types -pullPorts toPort showFn (p:ports) types = do - (x, types) <- pull1Port p types - (x:) <$> pullPorts toPort showFn ports types +pullPorts toPort showFn to_pull types = + -- the "state" here is the things still available to be pulled + (\(pulled, rest) -> pulled ++ rest) <$> runStateT (mapM pull1Port to_pull) types where - pull1Port :: PortName - -> [(a, ty)] - -> Checking ((a, ty), [(a, ty)]) - pull1Port p available = case partition ((== p) . toPort . fst) available of + pull1Port :: PortName -> StateT [(a, ty)] Checking (a, ty) + pull1Port p = StateT $ \available -> case partition ((== p) . toPort . fst) available of ([], _) -> err $ BadPortPull $ "Port not found: " ++ p ++ " in " ++ showFn available ([found], remaining) -> pure (found, remaining) (_, _) -> err $ AmbiguousPortPull p (showFn available)