Skip to content

Instantly share code, notes, and snippets.

@Solonarv
Created November 4, 2018 21:14
Show Gist options
  • Save Solonarv/8c82df1daaf8014295c995508d37994e to your computer and use it in GitHub Desktop.
Save Solonarv/8c82df1daaf8014295c995508d37994e to your computer and use it in GitHub Desktop.
{-# LANGUAGE DerivingStrategies #-}
import Data.HashMap.Strict -- package unordered-containers
import Data.Hashable -- package hashable
import Data.Int
import GHC.Generic
-- Attempting to model factorio's circuit system
data Channel = Wooden_Chest | Iron_Chest | Steel_Chest | Storage_Tank
| Transport_Belt | Fast_Transport_Belt | Express_Transport_Belt
| Underground_belt | Fast_Underground_Belt | Express_Underground_Belt
| Splitter | Fast_Splitter | Express_Splitter
-- ...
-- there are a *lot* of these
-- ...
| Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine
| A | B | C | D | E | F | G | H | I | J
| K | L | M | N | O | P | Q | R | S | T
| U | V | W | X | Y | Z
| Red | Green | Blue | Yellow | Pink | Cyan | White | Grey | Black
deriving stock (Show, Eq, Ord, Bounded)
allChannels :: [Channel]
allChannels = [minBound .. maxBound]
newtype Signal = Signal { value :: Int32 }
deriving stock (Show, Generic)
deriving anyclass (Hashable)
deriving newtype (Eq, Ord, Num, Integral)
newtype Wire = Wire { wireSignals :: HashMap Channel Signal }
-- | Remove all the (redundant) zero entries from a Wire
trimZeroes :: Wire -> Wire
trimZeroes = Wire . HashMap.filter (/= 0) . wireSignals
toSigFunc :: Wire -> (Channel -> Signal)
toSigFunc (Wire sigs) = \ch -> fromMaybe 0 $ HashMap.lookup ch sigs
fromSigFunc :: (Channel -> Signal) -> Wire
fromSigFunc f = trimZeroes . Wire $ HashMap.fromList [(ch, f ch) | ch <- allChannels]
wmap :: ((Channel,Signal) -> (Channel,Signal)) -> Wire -> Wire
wmap f wire = trimZeroes . Wire $ HashMap.fromListWith (+) [f (ch, sig ch) | ch <- allChannels]
where sig = toSigFunc wire
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment