invert-1.0: examples/billing-codes.hs
{-# LANGUAGE DeriveGeneric #-}
-- Enables stock deriving of the Generic class
{-# LANGUAGE DeriveAnyClass #-}
-- Enables deriving the GEnum class
{-# LANGUAGE DerivingStrategies #-}
-- Lets us explicitly say how we want to derive;
-- e.g. "deriving stock" or "deriving anyclass"
import Invert
import System.Exit (die)
data Product = Basic | Standard | Pro
deriving stock (Generic, Show, Eq)
deriving anyclass GEnum
data Frequency = Monthly | Annual
deriving stock (Generic, Show, Eq)
deriving anyclass GEnum
data Bill = Bill Product Frequency
deriving stock (Generic, Show, Eq)
deriving anyclass GEnum
encodeProduct :: Product -> String
encodeProduct x = case x of
Basic -> "p1"
Standard -> "p2"
Pro -> "p3"
encodeBill :: Bill -> Integer
encodeBill x = case x of
Bill Basic Monthly -> 10
Bill Basic Annual -> 11
Bill Standard Monthly -> 20
Bill Standard Annual -> 21
Bill Pro Monthly -> 30
Bill Pro Annual -> 31
decodeProduct :: String -> Maybe Product
decodeProduct = Invert.injection hashTable genum encodeProduct
decodeBill :: Integer -> Maybe Bill
decodeBill = Invert.injection hashTable genum encodeBill
main :: IO ()
main = do
encodeProduct Basic === "p1"
encodeProduct Standard === "p2"
decodeProduct "p1" === Just Basic
decodeProduct "xyz" === Nothing
encodeBill (Bill Basic Annual) === 11
encodeBill (Bill Pro Monthly) === 30
decodeBill 31 === Just (Bill Pro Annual)
decodeBill 50 === Nothing
(===) :: (Eq a, Show a) => a -> a -> IO ()
a === b | a == b = pure ()
| otherwise = die (show a <> " /= " <> show b)