Skip to content

Instantly share code, notes, and snippets.

@newton-migosi
Last active January 31, 2023 22:26
Show Gist options
  • Save newton-migosi/9299e878c6c8c44d9a195e7bfb8cc98c to your computer and use it in GitHub Desktop.
Save newton-migosi/9299e878c6c8c44d9a195e7bfb8cc98c to your computer and use it in GitHub Desktop.
literal translation of https://doc.rust-lang.org/rust-by-example/std/result.html .. not type checked, for illustration purposes only
data MathError
= DivisionByZero
| NonPositiveLogarithm
| NegativeSquareRoot
deriving Show
type MathResult = Either MathError Double
div :: Double -> Double -> MathResult
div x y =
if y == 0
then Left DivisionByZero
else Right(x / y)
sqrt :: Double -> MathResult
sqrt x =
if x < 0
then Left NegativeSquareRoot
else Right (x ** 0.5)
ln :: Double -> MathResult
ln x =
if x <= 0
then Left NonPositiveLogarithm
else Right (Math.log10 x)
-- op x y == sqrt(ln(x/y))
op :: Double -> Double -> MathResult
op x y = do
ratio <- div x y
ln' <- ln ratio
sqrt' <- sqrt ln'
return sqrt'
main :: IO ()
main = do
case (op 1 10) of
Left why -> throwError (show why)
Right res -> print res
-- The `Either` type is provided by the standard library as
-- data Either a b = Left a | Right b
@newton-migosi
Copy link
Author

newton-migosi commented Jan 31, 2023

Notice how op's definition isn't full of nested case statements.. the nesting logic is handled internally by the Either monad.. any time you see a do statement that means you've encountered monadic code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment