-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathinvert.hs
62 lines (49 loc) · 1.54 KB
/
invert.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
import GHC.Generics (Generic)
import Generics.Deriving.Enum (GEnum (genum))
import qualified Data.Map.Strict as Map
data Product = Basic | Standard | Pro
deriving stock (Generic, Show)
deriving anyclass GEnum
data Frequency = Monthly | Annual
deriving stock (Generic, Show)
deriving anyclass GEnum
data Bill = Bill Product Frequency
deriving stock (Generic, Show)
deriving anyclass GEnum
encodeProduct :: Product -> String
encodeProduct = \case
Basic -> "p1"
Standard -> "p2"
Pro -> "p3"
encodeBill :: Bill -> Integer
encodeBill = \case
Bill Basic Monthly -> 10
Bill Basic Annual -> 11
Bill Standard Monthly -> 20
Bill Standard Annual -> 21
Bill Pro Monthly -> 30
Bill Pro Annual -> 31
invert :: (GEnum a, Ord b) => (a -> b) -> b -> Maybe a
invert f =
let
reverseMap = foldMap (\a -> Map.singleton (f a) a) genum
in
\b -> Map.lookup b reverseMap
decodeProduct :: String -> Maybe Product
decodeProduct = invert encodeProduct
decodeBill :: Integer -> Maybe Bill
decodeBill = invert encodeBill
main =
do
putStrLn (encodeProduct Basic)
putStrLn (encodeProduct Standard)
putStrLn (show (decodeProduct "p1"))
putStrLn (show (decodeProduct "xyz"))
putStrLn (show (encodeBill (Bill Basic Annual)))
putStrLn (show (encodeBill (Bill Pro Monthly)))
putStrLn (show (decodeBill 31))
putStrLn (show (decodeBill 50))