Skip to content

Commit

Permalink
Use forM_/mapM_
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Jan 6, 2025
1 parent 2193e84 commit d58d237
Show file tree
Hide file tree
Showing 16 changed files with 196 additions and 236 deletions.
6 changes: 3 additions & 3 deletions src/swarm-doc/Swarm/Doc/Schema/Refined.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
module Swarm.Doc.Schema.Refined where

import Control.Applicative ((<|>))
import Control.Monad (unless)
import Data.Aeson
import Data.List.Extra (replace)
import Data.List.NonEmpty (NonEmpty)
Expand Down Expand Up @@ -122,9 +123,8 @@ toSwarmSchema rawSchema = do
theType <- maybe (fail "Unspecified sub-schema type") return maybeType
markdownDescription <- mapM getMarkdown $ _description rawSchema

if null (_properties rawSchema) || not (fromMaybe True (_additionalProperties rawSchema))
then return ()
else fail "All objects must specify '\"additionalProperties\": true'"
unless (null (_properties rawSchema) || not (fromMaybe True (_additionalProperties rawSchema))) $
fail "All objects must specify '\"additionalProperties\": true'"

return
SwarmSchema
Expand Down
24 changes: 11 additions & 13 deletions src/swarm-engine/Swarm/Game/ScenarioInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -188,21 +188,19 @@ loadScenarioDir scenarioInputs loadTestScenarios dir = do
True -> Just <$> readOrderFile orderFile
itemPaths <- sendIO $ keepYamlOrPublicDirectory dir =<< listDirectory dir

case morder of
Just order -> do
let missing = itemPaths \\ order
dangling = order \\ itemPaths
forM_ morder $ \order -> do
let missing = itemPaths \\ order
dangling = order \\ itemPaths

forM_ (NE.nonEmpty missing) $
warn
. OrderFileWarning (dirName </> orderFileName)
. MissingFiles
forM_ (NE.nonEmpty missing) $
warn
. OrderFileWarning (dirName </> orderFileName)
. MissingFiles

forM_ (NE.nonEmpty dangling) $
warn
. OrderFileWarning (dirName </> orderFileName)
. DanglingFiles
Nothing -> pure ()
forM_ (NE.nonEmpty dangling) $
warn
. OrderFileWarning (dirName </> orderFileName)
. DanglingFiles

-- Only keep the files from 00-ORDER.txt that actually exist.
let morder' = filter (`elem` itemPaths) <$> morder
Expand Down
22 changes: 10 additions & 12 deletions src/swarm-engine/Swarm/Game/State/Robot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -302,21 +302,19 @@ activateRobot rid = internalActiveRobots %= IS.insert rid
wakeUpRobotsDoneSleeping :: (Has (State Robots) sig m) => TickNumber -> m ()
wakeUpRobotsDoneSleeping time = do
mrids <- internalWaitingRobots . at time <<.= Nothing
case mrids of
Nothing -> return ()
Just rids -> do
robots <- use robotMap
let robotIdSet = IM.keysSet robots
wakeableRIDsSet = IS.fromList rids
forM_ mrids $ \rids -> do
robots <- use robotMap
let robotIdSet = IM.keysSet robots
wakeableRIDsSet = IS.fromList rids

-- Limit ourselves to the robots that have not expired in their sleep
newlyAlive = IS.intersection robotIdSet wakeableRIDsSet
-- Limit ourselves to the robots that have not expired in their sleep
newlyAlive = IS.intersection robotIdSet wakeableRIDsSet

internalActiveRobots %= IS.union newlyAlive
internalActiveRobots %= IS.union newlyAlive

-- These robots' wake times may have been moved "forward"
-- by 'wakeWatchingRobots'.
clearWatchingRobots wakeableRIDsSet
-- These robots' wake times may have been moved "forward"
-- by 'wakeWatchingRobots'.
clearWatchingRobots wakeableRIDsSet

-- | Clear the "watch" state of all of the
-- awakened robots
Expand Down
15 changes: 6 additions & 9 deletions src/swarm-engine/Swarm/Game/Step.hs
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,12 @@ gameTick = do
-- also save the current store into the robotContext so we can
-- restore it the next time we start a computation.
mr <- use (robotInfo . robotMap . at 0)
case mr of
Just r -> do
res <- use $ gameControls . replStatus
case res of
REPLWorking ty Nothing -> case getResult r of
Just v -> gameControls . replStatus .= REPLWorking ty (Just v)
Nothing -> pure ()
_otherREPLStatus -> pure ()
Nothing -> pure ()
forM_ mr $ \r -> do
res <- use $ gameControls . replStatus
case res of
REPLWorking ty Nothing -> forM_ (getResult r) $ \v ->
gameControls . replStatus .= REPLWorking ty (Just v)
_otherREPLStatus -> pure ()

-- Possibly update the view center.
modify recalcViewCenterAndRedraw
Expand Down
56 changes: 26 additions & 30 deletions src/swarm-engine/Swarm/Game/Step/Const.hs
Original file line number Diff line number Diff line change
Expand Up @@ -214,22 +214,20 @@ execConst runChildProg c vs s k = do
-- If unobstructed, the robot will move even if
-- there is nothing to push.
maybeCurrentE <- entityAt nextLoc
case maybeCurrentE of
Just e -> do
-- Make sure there's nothing already occupying the destination
nothingHere <- isNothing <$> entityAt placementLoc
nothingHere `holdsOrFail` ["Something is in the way!"]

let verbed = verbedGrabbingCmd Push'
-- Ensure it can be pushed.
omni <- isPrivilegedBot
(omni || e `hasProperty` Pushable || e `hasProperty` Pickable && not (e `hasProperty` Liquid))
`holdsOrFail` ["The", e ^. entityName, "here can't be", verbed <> "."]

-- Place the entity and remove it from previous loc
updateEntityAt nextLoc (const Nothing)
updateEntityAt placementLoc (const (Just e))
Nothing -> return ()
forM_ maybeCurrentE $ \e -> do
-- Make sure there's nothing already occupying the destination
nothingHere <- isNothing <$> entityAt placementLoc
nothingHere `holdsOrFail` ["Something is in the way!"]

let verbed = verbedGrabbingCmd Push'
-- Ensure it can be pushed.
omni <- isPrivilegedBot
(omni || e `hasProperty` Pushable || e `hasProperty` Pickable && not (e `hasProperty` Liquid))
`holdsOrFail` ["The", e ^. entityName, "here can't be", verbed <> "."]

-- Place the entity and remove it from previous loc
updateEntityAt nextLoc (const Nothing)
updateEntityAt placementLoc (const (Just e))

updateRobotLocation loc nextLoc
return $ mkReturn ()
Expand Down Expand Up @@ -1657,7 +1655,7 @@ execConst runChildProg c vs s k = do
(mAch False)

selfDestruct .= True
maybe (return ()) grantAchievementForRobot (mAch True)
forM_ (mAch True) grantAchievementForRobot

moveInDirection :: (HasRobotStepState sig m, Has (Lift IO) sig m) => Heading -> m CESK
moveInDirection orientation = do
Expand All @@ -1676,19 +1674,17 @@ execConst runChildProg c vs s k = do
MoveFailureHandler ->
m ()
applyMoveFailureEffect maybeFailure failureHandler =
case maybeFailure of
Nothing -> return ()
Just failureMode -> case failureHandler failureMode of
IgnoreFail -> return ()
Destroy -> destroyIfNotBase $ \b -> case (b, failureMode) of
(True, PathLiquid _) -> Just RobotIntoWater -- achievement for drowning
_ -> Nothing
ThrowExn -> throwError . cmdExn c $
case failureMode of
PathBlockedBy ent -> case ent of
Just e -> ["There is a", e ^. entityName, "in the way!"]
Nothing -> ["There is nothing to travel on!"]
PathLiquid e -> ["There is a dangerous liquid", e ^. entityName, "in the way!"]
forM_ maybeFailure $ \failureMode -> case failureHandler failureMode of
IgnoreFail -> return ()
Destroy -> destroyIfNotBase $ \b -> case (b, failureMode) of
(True, PathLiquid _) -> Just RobotIntoWater -- achievement for drowning
_ -> Nothing
ThrowExn -> throwError . cmdExn c $
case failureMode of
PathBlockedBy ent -> case ent of
Just e -> ["There is a", e ^. entityName, "in the way!"]
Nothing -> ["There is nothing to travel on!"]
PathLiquid e -> ["There is a dangerous liquid", e ^. entityName, "in the way!"]

-- Determine the move failure mode and apply the corresponding effect.
checkMoveAhead ::
Expand Down
50 changes: 22 additions & 28 deletions src/swarm-engine/Swarm/Game/Step/Util/Command.hs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,17 @@ ensureCanExecute ::
Const ->
m ()
ensureCanExecute c =
gets @Robot (constCapsFor c) >>= \case
Nothing -> pure ()
Just cap -> do
isPrivileged <- isPrivilegedBot
-- Privileged robots can execute commands regardless
-- of equipped devices, and without expending
-- a capability's exercise cost.
unless isPrivileged $ do
robotCaps <- use robotCapabilities
let capProviders = M.lookup cap $ getMap robotCaps
case capProviders of
Nothing -> throwError $ Incapable FixByEquip (R.singletonCap cap) (TConst c)
Just rawCosts -> payExerciseCost c rawCosts
gets @Robot (constCapsFor c) >>= mapM_ \cap -> do
isPrivileged <- isPrivilegedBot
-- Privileged robots can execute commands regardless
-- of equipped devices, and without expending
-- a capability's exercise cost.
unless isPrivileged $ do
robotCaps <- use robotCapabilities
let capProviders = M.lookup cap $ getMap robotCaps
case capProviders of
Nothing -> throwError $ Incapable FixByEquip (R.singletonCap cap) (TConst c)
Just rawCosts -> payExerciseCost c rawCosts

payExerciseCost ::
( Has (State Robot) sig m
Expand Down Expand Up @@ -212,14 +210,12 @@ onTarget rid act = do
True -> act
False -> do
mtgt <- use (robotInfo . robotMap . at rid)
case mtgt of
Nothing -> return ()
Just tgt -> do
tgt' <- execState @Robot tgt act
zoomRobots $
if tgt' ^. selfDestruct
then deleteRobot rid
else robotMap . ix rid .= tgt'
forM_ mtgt $ \tgt -> do
tgt' <- execState @Robot tgt act
zoomRobots $
if tgt' ^. selfDestruct
then deleteRobot rid
else robotMap . ix rid .= tgt'

-- | Enforces validity of the robot's privileged status to receive
-- an achievement.
Expand Down Expand Up @@ -292,13 +288,11 @@ isNearbyOrExempt privileged myLoc otherLoc =
updateDiscoveredEntities :: (HasRobotStepState sig m) => Entity -> m ()
updateDiscoveredEntities e = do
allDiscovered <- use $ discovery . allDiscoveredEntities
if E.contains0plus e allDiscovered
then pure ()
else do
let newAllDiscovered = E.insertCount 1 e allDiscovered
updateAvailableRecipes (newAllDiscovered, newAllDiscovered) e
updateAvailableCommands e
discovery . allDiscoveredEntities .= newAllDiscovered
unless (E.contains0plus e allDiscovered) $ do
let newAllDiscovered = E.insertCount 1 e allDiscovered
updateAvailableRecipes (newAllDiscovered, newAllDiscovered) e
updateAvailableCommands e
discovery . allDiscoveredEntities .= newAllDiscovered

-- | Update the availableRecipes list.
-- This implementation is not efficient:
Expand Down
21 changes: 10 additions & 11 deletions src/swarm-lang/Swarm/Language/Typecheck.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,17 +1160,16 @@ check s@(CSyntax l t cs) expected = addLocToTypeErr l $ case t of
SLam x mxTy body -> do
(argTy, resTy) <- decomposeFunTy s (Expected, expected)
traverse_ (adaptToTypeErr l KindErr . checkKind) mxTy
case toU mxTy of
Just xTy -> do
res <- argTy U.=:= xTy
case res of
-- Generate a special error when the explicit type annotation
-- on a lambda doesn't match the expected type,
-- e.g. (\x:Int. x + 2) : Text -> Int, since the usual
-- "expected/but got" language would probably be confusing.
Left _ -> throwTypeErr l $ LambdaArgMismatch (joined argTy xTy)
Right _ -> return ()
Nothing -> return ()
forM_ (toU mxTy) $ \xTy -> do
res <- argTy U.=:= xTy
case res of
-- Generate a special error when the explicit type annotation
-- on a lambda doesn't match the expected type,
-- e.g. (\x:Int. x + 2) : Text -> Int, since the usual
-- "expected/but got" language would probably be confusing.
Left _ -> throwTypeErr l $ LambdaArgMismatch (joined argTy xTy)
Right _ -> return ()

body' <- withBinding @UPolytype (lvVar x) (mkTrivPoly argTy) $ check body resTy
return $ Syntax' l (SLam x mxTy body') cs (UTyFun argTy resTy)

Expand Down
5 changes: 2 additions & 3 deletions src/swarm-scenario/Swarm/Game/Entity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -506,9 +506,8 @@ validateEntityAttrRefs validAttrs es =
-- from a file; see 'loadEntities'.
buildEntityMap :: Has (Throw LoadingFailure) sig m => [Entity] -> m EntityMap
buildEntityMap es = do
case findDup (map fst namedEntities) of
Nothing -> return ()
Just duped -> throwError $ Duplicate Entities duped
forM_ (findDup $ map fst namedEntities) $
throwError . Duplicate Entities
case combineEntityCapsM entsByName es of
Left x -> throwError $ CustomMessage x
Right ebc ->
Expand Down
5 changes: 2 additions & 3 deletions src/swarm-scenario/Swarm/Game/Scenario.hs
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,8 @@ instance FromJSONE ScenarioInputs Scenario where
combinedTEM <- getE

let TerrainEntityMaps _tm emCombined = combinedTEM
case filter (isNothing . (`lookupEntityName` emCombined)) known of
[] -> return ()
unk -> failT ["Unknown entities in 'known' list:", T.intercalate ", " unk]
forM_ (NE.nonEmpty $ filter (isNothing . (`lookupEntityName` emCombined)) known) $ \unk ->
failT ["Unknown entities in 'known' list:", T.intercalate ", " $ NE.toList unk]

-- parse robots and build RobotMap
rs <- v ..: "robots"
Expand Down
25 changes: 11 additions & 14 deletions src/swarm-scenario/Swarm/Game/Scenario/Objective/Validation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
module Swarm.Game.Scenario.Objective.Validation where

import Control.Lens (view, (^.))
import Control.Monad (unless)
import Control.Monad (forM_, unless)
import Data.Foldable (for_, toList)
import Data.Maybe (fromMaybe, mapMaybe)
import Data.Set qualified as Set
Expand All @@ -29,19 +29,16 @@ validateObjectives ::
[Objective] ->
m [Objective]
validateObjectives objectives = do
for_ objectives $ \x -> case x ^. objectivePrerequisite of
Just p ->
unless (null remaining) $
failT
[ "Reference to undefined objective(s)"
, T.intercalate ", " (map quote $ Set.toList remaining) <> "."
, "Defined are:"
, T.intercalate ", " (map quote $ Set.toList allIds)
]
where
refs = Set.fromList $ toList $ logic p
remaining = Set.difference refs allIds
Nothing -> return ()
for_ objectives $ \x -> forM_ (x ^. objectivePrerequisite) $ \p ->
let refs = Set.fromList $ toList $ logic p
remaining = Set.difference refs allIds
in unless (null remaining) $
failT
[ "Reference to undefined objective(s)"
, T.intercalate ", " (map quote $ Set.toList remaining) <> "."
, "Defined are:"
, T.intercalate ", " (map quote $ Set.toList allIds)
]

either (fail . T.unpack) return $
failOnCyclicGraph "Prerequisites" (fromMaybe "N/A" . view objectiveId) edges
Expand Down
Loading

0 comments on commit d58d237

Please sign in to comment.