Advertisement
banovski

“Maybe a” emulation: monadic properties

Aug 1st, 2024 (edited)
519
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 3.25 KB | Source Code | 0 0
  1. -- "Maybe a" emulation: monadic properties
  2.  
  3. data OptionType a
  4.   = Empty
  5.   | NonEmpty a
  6.   deriving (Show, Eq)
  7.  
  8. instance Functor OptionType where
  9.   fmap _ Empty = Empty
  10.   fmap f (NonEmpty a) = NonEmpty $ f a
  11.  
  12. instance Applicative OptionType where
  13.   pure = NonEmpty
  14.   (<*>) (NonEmpty a) (NonEmpty b) = NonEmpty $ a b
  15.  
  16. instance Monad OptionType where
  17.   return = NonEmpty
  18. -- the 'bind' operator is the >>= thingy :-)
  19.   (>>=) Empty f = Empty
  20.   (>>=) (NonEmpty a) f = f a
  21.  
  22. increment :: Int -> OptionType Int
  23. increment x = NonEmpty (x + 1)
  24.  
  25. feedingEmptyOptionalValue :: OptionType Int
  26. feedingEmptyOptionalValue = Empty >>= increment
  27.  
  28. singleFeeding :: OptionType Int
  29. singleFeeding = NonEmpty 7 >>= increment
  30.  
  31. doubleFeeding :: OptionType Int
  32. doubleFeeding = NonEmpty 7 >>= increment >>= increment
  33.  
  34. fuckUpPipeline :: OptionType Int
  35. fuckUpPipeline = NonEmpty 7 >>= increment >>= (\_ -> Empty) >>= increment
  36.  
  37. outputText =
  38.   [ "1. An empty optional value: "
  39.   , show (Empty :: OptionType Int)
  40.   , "2. An non-empty optional value: "
  41.   , show (NonEmpty 7)
  42.   , "3. Feeding an empty optional value to the increment function:"
  43.   , "Empty >>= increment → "
  44.   , show feedingEmptyOptionalValue
  45.   , "4. Feeding an non-empty optional value to the increment function:"
  46.   , "NonEmpty 7 >>= increment → "
  47.   , show singleFeeding
  48.   , "5. A two-section pipeline with the increment function:"
  49.   , "NonEmpty 7 >>= increment >>= increment → "
  50.   , show doubleFeeding
  51.   , "6. A three-section pipeline showcasing failure propagation:"
  52.   , "NonEmpty 7 >>= increment >>= (\\_ -> Empty) >>= increment → "
  53.   , show fuckUpPipeline
  54.   , "7. The first monadic law: return a >>= h ≡ h a:"
  55.   , "(return 7 >>= increment) == increment 7 →"
  56.   , show $ (return 7 >>= increment) == increment 7
  57.   , "8. The second monadic law: m >>= return ≡ m:"
  58.   , "(NonEmpty 7 >>= return) == NonEmpty 7 →"
  59.   , show $ (NonEmpty 7 >>= return) == NonEmpty 7
  60.   , "9. The third monadic law: (m >>= g) >>= h ≡ m >>= (\\x -> g x >>= h):"
  61.   , "((NonEmpty 7 >>= (\\_ -> Empty)) >>= increment) == (NonEmpty 7 >>= (\\x -> (\\_ -> Empty) x >>= increment)) →"
  62.   , show $ ((NonEmpty 7 >>= (\_ -> Empty)) >>= increment) == (NonEmpty 7 >>= (\x -> (\_ -> Empty) x >>= increment))
  63.   ]
  64.  
  65. main :: IO ()
  66. main = mapM_ putStrLn outputText
  67.  
  68. -- 1. An empty optional value:
  69. -- Empty
  70. -- 2. An non-empty optional value:
  71. -- NonEmpty 7
  72. -- 3. Feeding an empty optional value to the increment function:
  73. -- Empty >>= increment →
  74. -- Empty
  75. -- 4. Feeding an non-empty optional value to the increment function:
  76. -- NonEmpty 7 >>= increment →
  77. -- NonEmpty 8
  78. -- 5. A two-section pipeline with the increment function:
  79. -- NonEmpty 7 >>= increment >>= increment →
  80. -- NonEmpty 9
  81. -- 6. A three-section pipeline showcasing failure propagation:
  82. -- NonEmpty 7 >>= increment >>= (\_ -> Empty) >>= increment →
  83. -- Empty
  84. -- 7. The first monadic law: return a >>= h ≡ h a:
  85. -- (return 7 >>= increment) == increment 7 →
  86. -- True
  87. -- 8. The second monadic law: m >>= return ≡ m:
  88. -- (NonEmpty 7 >>= return) == NonEmpty 7 →
  89. -- True
  90. -- 9. The third monadic law: (m >>= g) >>= h ≡ m >>= (\x -> g x >>= h):
  91. -- ((NonEmpty 7 >>= (\_ -> Empty)) >>= increment) == (NonEmpty 7 >>= (\x -> (\_ -> Empty) x >>= increment)) →
  92. -- True
  93.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement