Skip to content

Commit

Permalink
Use 'enumerate' from the 'extra' package (#2003)
Browse files Browse the repository at this point in the history
Use [`enumerate`](https://hackage.haskell.org/package/extra-1.7.16/docs/Data-List-Extra.html#v:enumerate) instead of defining `listEnums` ourselves.

Also discovered a "safer" implementation of nonempty enumerations, which lets of remove the `Data.List.NonEmpty.fromList` hlint exclusion.
  • Loading branch information
kostmo authored Jul 1, 2024
1 parent 4015997 commit 1688f1e
Show file tree
Hide file tree
Showing 22 changed files with 56 additions and 53 deletions.
1 change: 0 additions & 1 deletion .hlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
- functions:
- {name: Data.List.head, within: []}
- {name: Prelude.head, within: [Swarm.Web.Tournament.Database.Query]}
- {name: Data.List.NonEmpty.fromList, within: [Swarm.Util]}
- {name: Prelude.tail, within: []}
- {name: Prelude.!!, within: [Swarm.Util.indexWrapNonEmpty, TestEval]}
- {name: undefined, within: [Swarm.Language.Key, TestUtil]}
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-doc/Swarm/Doc/Command.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
module Swarm.Doc.Command where

import Data.Aeson (ToJSON)
import Data.List.Extra (enumerate)
import Data.List.NonEmpty qualified as NE
import Data.Set (Set)
import Data.Set qualified as Set
Expand All @@ -16,7 +17,6 @@ import Swarm.Language.Syntax
import Swarm.Language.Syntax.CommandMetadata
import Swarm.Language.Typecheck (inferConst)
import Swarm.Language.Types
import Swarm.Util (listEnums)

data DerivedAttrs = DerivedAttrs
{ hasActorTarget :: Bool
Expand Down Expand Up @@ -54,7 +54,7 @@ mkEntry c =
{ hasActorTarget = operatesOnActor inputArgs
, pureComputation = Set.null cmdEffects
, modifiesEnvironment = Mutation EntityChange `Set.member` cmdEffects
, modifiesRobot = not . Set.disjoint cmdEffects . Set.fromList $ map (Mutation . RobotChange) listEnums
, modifiesRobot = not . Set.disjoint cmdEffects . Set.fromList $ map (Mutation . RobotChange) enumerate
, movesRobot = Mutation (RobotChange PositionChange) `Set.member` cmdEffects
, returnsValue = theOutputType /= TyCmd TyUnit
, outputType = show theOutputType
Expand Down
5 changes: 3 additions & 2 deletions src/swarm-doc/Swarm/Doc/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Control.Lens (view, (^.))
import Control.Monad (zipWithM, zipWithM_)
import Data.Containers.ListUtils (nubOrd)
import Data.Foldable (toList)
import Data.List.Extra (enumerate)
import Data.Map.Lazy (Map, (!))
import Data.Map.Lazy qualified as Map
import Data.Maybe (fromMaybe, mapMaybe)
Expand All @@ -43,7 +44,7 @@ import Swarm.Game.Scenario (GameStateInputs (..), ScenarioInputs (..), loadStand
import Swarm.Game.World.Gen (extractEntities)
import Swarm.Game.World.Typecheck (Some (..), TTerm)
import Swarm.Language.Key (specialKeyNames)
import Swarm.Util (both, listEnums)
import Swarm.Util (both)
import Text.Dot (Dot, NodeId, (.->.))
import Text.Dot qualified as Dot

Expand Down Expand Up @@ -83,7 +84,7 @@ generateDocs = \case
putStrLn $ "-- " <> show et
putStrLn $ replicate 40 '-'
generateEditorKeywords et
mapM_ editorGen listEnums
mapM_ editorGen enumerate
SpecialKeyNames -> generateSpecialKeyNames
CheatSheet address s -> makeWikiPage address s
TutorialCoverage -> renderTutorialProgression >>= putStrLn . T.unpack
Expand Down
5 changes: 3 additions & 2 deletions src/swarm-doc/Swarm/Doc/Wiki/Cheatsheet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Control.Lens (view, (^.))
import Control.Lens.Combinators (to)
import Data.Foldable (find, toList)
import Data.List (transpose)
import Data.List.Extra (enumerate)
import Data.Map.Lazy qualified as Map
import Data.Maybe (isJust)
import Data.Set qualified as S
Expand All @@ -41,7 +42,7 @@ import Swarm.Language.Syntax (Const (..))
import Swarm.Language.Syntax qualified as Syntax
import Swarm.Language.Text.Markdown as Markdown (docToMark)
import Swarm.Language.Typecheck (inferConst)
import Swarm.Util (listEnums, showT)
import Swarm.Util (showT)

-- * Types

Expand Down Expand Up @@ -189,7 +190,7 @@ capabilityTable a em cs = T.unlines $ header <> map (listToRow mw) capabilityRow
header = [listToRow mw capabilityHeader, separatingLine mw]

capabilityPage :: PageAddress -> EntityMap -> Text
capabilityPage a em = capabilityTable a em listEnums
capabilityPage a em = capabilityTable a em enumerate

-- ** Entities

Expand Down
4 changes: 2 additions & 2 deletions src/swarm-engine/Swarm/Game/Step/Util/Inspect.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ import Control.Effect.Lens
import Control.Lens hiding (from, use, (%=), (<.>))
import Data.IntMap qualified as IM
import Data.List (find)
import Data.List.Extra (enumerate)
import Data.Text (Text)
import Swarm.Game.Location
import Swarm.Game.Robot
import Swarm.Game.State
import Swarm.Game.State.Robot
import Swarm.Game.Universe
import Swarm.Language.Syntax.Direction
import Swarm.Util (listEnums)

-- * World queries

getNeighborLocs :: Cosmic Location -> [Cosmic Location]
getNeighborLocs loc = map (offsetBy loc . flip applyTurn north . DRelative . DPlanar) listEnums
getNeighborLocs loc = map (offsetBy loc . flip applyTurn north . DRelative . DPlanar) enumerate

-- | Get the robot with a given ID.
robotWithID :: (Has (State GameState) sig m) => RID -> m (Maybe Robot)
Expand Down
5 changes: 3 additions & 2 deletions src/swarm-lang/Swarm/Language/Parser/Lex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import Control.Lens (use, view, (%=), (.=))
import Control.Monad (void)
import Data.Char (isLower, isUpper)
import Data.Containers.ListUtils (nubOrd)
import Data.List.Extra (enumerate)
import Data.Sequence qualified as Seq
import Data.Set (Set)
import Data.Set qualified as S
Expand All @@ -58,7 +59,7 @@ import Swarm.Language.Parser.Core
import Swarm.Language.Syntax
import Swarm.Language.Syntax.Direction
import Swarm.Language.Types (baseTyName)
import Swarm.Util (failT, listEnums, squote)
import Swarm.Util (failT, squote)
import Text.Megaparsec
import Text.Megaparsec.Char
import Text.Megaparsec.Char.Lexer qualified as L
Expand Down Expand Up @@ -156,7 +157,7 @@ operatorChar = T.singleton <$> oneOf opChars

-- | Names of base types built into the language.
baseTypeNames :: [Text]
baseTypeNames = map baseTyName listEnums
baseTypeNames = map baseTyName enumerate

-- | Names of types built into the language.
primitiveTypeNames :: [Text]
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-lang/Swarm/Language/Parser/Type.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Control.Monad (join)
import Control.Monad.Combinators (many)
import Control.Monad.Combinators.Expr (Operator (..), makeExprParser)
import Data.Fix (Fix (..), foldFix)
import Data.List.Extra (enumerate)
import Data.Maybe (fromMaybe)
import Data.Set qualified as S
import Swarm.Language.Parser.Core (LanguageVersion (..), Parser, languageVersion)
Expand All @@ -32,7 +33,6 @@ import Swarm.Language.Parser.Lex (
)
import Swarm.Language.Parser.Record (parseRecord)
import Swarm.Language.Types
import Swarm.Util (listEnums)
import Text.Megaparsec (choice, optional, some, (<|>))
import Witch (from)

Expand Down Expand Up @@ -103,7 +103,7 @@ parseTyCon = do
SwarmLang0_5 -> reserved
-- The latest version requires them to be uppercase
SwarmLangLatest -> reservedCS
choice (map (\b -> TCBase b <$ reservedCase (baseTyName b)) listEnums)
choice (map (\b -> TCBase b <$ reservedCase (baseTyName b)) enumerate)
<|> TCCmd <$ reservedCase "Cmd"
<|> TCUser <$> tyName

Expand Down
8 changes: 4 additions & 4 deletions src/swarm-lang/Swarm/Language/Syntax/Constants.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ module Swarm.Language.Syntax.Constants (
import Data.Aeson.Types hiding (Key)
import Data.Data (Data)
import Data.Int (Int32)
import Data.List.Extra (enumerate)
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Text hiding (filter, length, map)
import Data.Text qualified as T
import GHC.Generics (Generic)
import Swarm.Language.Syntax.CommandMetadata
import Swarm.Util qualified as Util
import Witch.From (from)
import Swarm.Util (showT)

------------------------------------------------------------
-- Constants
Expand Down Expand Up @@ -312,7 +312,7 @@ data Const
deriving (Eq, Ord, Enum, Bounded, Data, Show, Generic, FromJSON, ToJSON, FromJSONKey, ToJSONKey)

allConst :: [Const]
allConst = Util.listEnums
allConst = enumerate

data ConstInfo = ConstInfo
{ syntax :: Text
Expand Down Expand Up @@ -887,7 +887,7 @@ constInfo c = case c of
}

lowShow :: Show a => a -> Text
lowShow a = toLower (from (show a))
lowShow = toLower . showT

-- | Maximum perception distance for
-- 'Chirp' and 'Sniff' commands
Expand Down
6 changes: 3 additions & 3 deletions src/swarm-scenario/Swarm/Game/Achievement/Definitions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ module Swarm.Game.Achievement.Definitions (
) where

import Data.Aeson
import Data.List.Extra (enumerate)
import Data.Text (Text)
import GHC.Generics (Generic)
import Swarm.Language.Syntax (Syntax)
import Swarm.Language.Text.Markdown (Document)
import Swarm.Util

-- | How hard do we expect the achievement to be?
data ExpectedEffort
Expand Down Expand Up @@ -134,5 +134,5 @@ instance ToJSON GameplayAchievement
-- | List of all possible achievements.
listAchievements :: [CategorizedAchievement]
listAchievements =
map GlobalAchievement listEnums
<> map GameplayAchievement listEnums
map GlobalAchievement enumerate
<> map GameplayAchievement enumerate
7 changes: 4 additions & 3 deletions src/swarm-topography/Swarm/Game/Location.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import Data.Aeson (FromJSONKey, ToJSONKey)
import Data.Function (on, (&))
import Data.Int (Int32)
import Data.List (nub)
import Data.List.Extra (enumerate)
import Data.Map (Map)
import Data.Map qualified as M
import Data.Yaml (FromJSON (parseJSON), ToJSON (toJSON))
Expand Down Expand Up @@ -146,7 +147,7 @@ applyTurn d = case d of
-- Only absolute directions are mapped.
cardinalDirs :: M.Map Heading AbsoluteDir
cardinalDirs =
M.fromList $ map (toHeading &&& id) Util.listEnums
M.fromList $ map (toHeading &&& id) enumerate

-- | Possibly convert a heading into a 'Direction'---that is, if the
-- vector happens to be a unit vector in one of the cardinal
Expand Down Expand Up @@ -174,7 +175,7 @@ relativeTo :: AbsoluteDir -> AbsoluteDir -> PlanarRelativeDir
relativeTo targetDir referenceDir =
toEnum indexDiff
where
enumCount = length (Util.listEnums :: [AbsoluteDir])
enumCount = length (enumerate :: [AbsoluteDir])
indexDiff = ((-) `on` fromEnum) targetDir referenceDir `mod` enumCount

-- | Compute the absolute direction nearest to a given 'Heading'.
Expand All @@ -189,7 +190,7 @@ nearestDirection coord =

index :: Int
index = round $ fromIntegral (length orderedDirs) * angle
orderedDirs = Util.listEnumsNonempty
orderedDirs = Util.enumerateNonEmpty

-- | Convert a 'Direction' into a corresponding 'Heading'. Note that
-- this only does something reasonable for 'DNorth', 'DSouth', 'DEast',
Expand Down
3 changes: 2 additions & 1 deletion src/swarm-tui/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Control.Monad.State (MonadState, execState)
import Data.Bits
import Data.Foldable (toList)
import Data.Int (Int32)
import Data.List.Extra (enumerate)
import Data.List.NonEmpty (NonEmpty (..))
import Data.List.NonEmpty qualified as NE
import Data.Map qualified as M
Expand Down Expand Up @@ -970,7 +971,7 @@ doGoalUpdates = do
focusRing $
map GoalWidgets $
if hasMultiple
then listEnums
then enumerate
else [GoalSummary]

-- The "uiGoal" field is necessary at least to "persist" the data that is needed
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-tui/Swarm/TUI/Editor/Model.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Swarm.TUI.Editor.Model where
import Brick.Focus
import Brick.Widgets.List qualified as BL
import Control.Lens hiding (from, (.=), (<.>))
import Data.List.Extra (enumerate)
import Data.Map qualified as M
import Data.Vector qualified as V
import Swarm.Game.Display (Display)
Expand All @@ -18,7 +19,6 @@ import Swarm.Game.Terrain (TerrainType)
import Swarm.Game.Universe
import Swarm.Game.World.Coords
import Swarm.TUI.Model.Name
import Swarm.Util
import System.Clock

data BoundsSelectionStep
Expand Down Expand Up @@ -82,7 +82,7 @@ initialWorldEditor ts =
(BL.list TerrainList (V.fromList []) 1)
(BL.list EntityPaintList (V.fromList []) 1)
bounds
(focusRing $ map WorldEditorPanelControl listEnums)
(focusRing $ map WorldEditorPanelControl enumerate)
"mymap.yaml"
Nothing
where
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-tui/Swarm/TUI/Launch/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Brick.Widgets.FileBrowser qualified as FB
import Control.Lens
import Control.Monad (forM_, when)
import Control.Monad.IO.Class (liftIO)
import Data.List.Extra (enumerate)
import Data.Maybe (listToMaybe)
import Graphics.Vty qualified as V
import Swarm.Game.Scenario.Status (ParameterizableLaunchParams (LaunchParams))
Expand All @@ -23,7 +24,6 @@ import Swarm.TUI.Model
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.StateUpdate
import Swarm.TUI.Model.UI
import Swarm.Util (listEnums)

updateFocusRing :: EditingLaunchParams -> EventM Name LaunchOptions ()
updateFocusRing parsedParams = do
Expand All @@ -35,7 +35,7 @@ updateFocusRing parsedParams = do
maybeCurrentFocus = focusGetCurrent currentRing
refocusRing = maybe id focusSetCurrent maybeCurrentFocus

controls . scenarioConfigFocusRing .= refocusRing (makeFocusRingWith $ modifyRingMembers listEnums)
controls . scenarioConfigFocusRing .= refocusRing (makeFocusRingWith $ modifyRingMembers enumerate)

cacheValidatedInputs :: EventM Name LaunchOptions ()
cacheValidatedInputs = do
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-tui/Swarm/TUI/Launch/Prep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Control.Carrier.Throw.Either (runThrow)
import Control.Lens ((.=), (^.))
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Functor.Identity (runIdentity)
import Data.List.Extra (enumerate)
import Data.Text qualified as T
import Swarm.Game.Failure (SystemFailure)
import Swarm.Game.Scenario.Status (ParameterizableLaunchParams (..), ScenarioInfoPair, getLaunchParams, scenarioStatus)
Expand All @@ -25,7 +26,6 @@ import Swarm.Game.World.Gen (Seed)
import Swarm.Language.Pretty (prettyText)
import Swarm.TUI.Launch.Model
import Swarm.TUI.Model.Name
import Swarm.Util (listEnums)
import Swarm.Util.Effect (withThrow)
import System.FilePath (takeDirectory)
import Text.Read (readEither)
Expand Down Expand Up @@ -87,7 +87,7 @@ initConfigPanel = do
(LaunchParams (Right Nothing) (Right Nothing))
where
myForm = initEditorWidget ""
ring = makeFocusRingWith listEnums
ring = makeFocusRingWith enumerate

initFileBrowserWidget ::
(MonadIO m) =>
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-tui/Swarm/TUI/Model/Goal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Brick.Focus
import Brick.Widgets.List qualified as BL
import Control.Lens (makeLenses, view, (^..))
import Data.Aeson
import Data.List.Extra (enumerate)
import Data.List.NonEmpty (NonEmpty, nonEmpty)
import Data.List.NonEmpty qualified as NE
import Data.Map (Map)
Expand All @@ -22,7 +23,6 @@ import Servant.Docs qualified as SD
import Swarm.Game.Scenario.Objective
import Swarm.Game.Scenario.Objective.WinCheck
import Swarm.TUI.Model.Name
import Swarm.Util (listEnums)

-- | These are intended to be used as keys in a map
-- of lists of goals.
Expand Down Expand Up @@ -90,7 +90,7 @@ emptyGoalDisplay =
GoalDisplay
(GoalTracking mempty mempty)
(BL.list (GoalWidgets ObjectivesList) mempty 1)
(focusRing $ map GoalWidgets listEnums)
(focusRing $ map GoalWidgets enumerate)

hasAnythingToShow :: GoalTracking -> Bool
hasAnythingToShow (GoalTracking ann g) = not (null ann && null g)
Expand Down
4 changes: 2 additions & 2 deletions src/swarm-tui/Swarm/TUI/Model/Menu.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Swarm.TUI.Model.Menu where
import Brick.Widgets.Dialog (Dialog)
import Brick.Widgets.List qualified as BL
import Control.Lens hiding (from, (<.>))
import Data.List.Extra (enumerate)
import Data.List.NonEmpty (NonEmpty (..))
import Data.List.NonEmpty qualified as NE
import Data.Map qualified as M
Expand All @@ -32,7 +33,6 @@ import Swarm.Game.ScenarioInfo (
)
import Swarm.Game.World.Gen (Seed)
import Swarm.TUI.Model.Name
import Swarm.Util
import System.FilePath (dropTrailingPathSeparator, splitPath, takeFileName)
import Witch (into)

Expand Down Expand Up @@ -96,7 +96,7 @@ data Menu
| AboutMenu

mainMenu :: MainMenuEntry -> BL.List Name MainMenuEntry
mainMenu e = BL.list MenuList (V.fromList listEnums) 1 & BL.listMoveToElement e
mainMenu e = BL.list MenuList (V.fromList enumerate) 1 & BL.listMoveToElement e

makePrisms ''Menu

Expand Down
Loading

0 comments on commit 1688f1e

Please sign in to comment.