Skip to content

Instantly share code, notes, and snippets.

@mkohlhaas
Last active January 3, 2022 15:29
Show Gist options
  • Save mkohlhaas/829127bad61a00c455bc1a67addb7487 to your computer and use it in GitHub Desktop.
Save mkohlhaas/829127bad61a00c455bc1a67addb7487 to your computer and use it in GitHub Desktop.
module Ch07a1 where
import Prelude (Unit, discard, (<>))
import Effect (Effect)
import Effect.Console (log)
-------------------- JS Primitives --------------------------------------------------------
foreign import ordIntImpl :: Ordering -> Ordering -> Ordering -> Int -> Int -> Ordering
foreign import eqIntImpl :: Int -> Int -> Boolean
foreign import showIntImpl :: Int -> String
foreign import showStringImpl :: String -> String
-------------------- Functions ------------------------------------------------------------
apply :: ∀ a b. (a -> b) -> a -> b
apply f = f
infixr 0 apply as $
-----------------
-- Comparisons --
-----------------
lessThan :: ∀ a. Ord a => a -> a -> Boolean
lessThan a b = case compare a b of
LT -> true
_ -> false
lessThanOrEq :: ∀ a. Ord a => a -> a -> Boolean
lessThanOrEq a b = case compare a b of
GT -> false
_ -> true
greaterThan :: ∀ a. Ord a => a -> a -> Boolean
greaterThan a b = case compare a b of
GT -> true
_ -> false
greaterThanOrEq :: ∀ a. Ord a => a -> a -> Boolean
greaterThanOrEq a b = case compare a b of
LT -> false
_ -> true
infixl 4 lessThanOrEq as <=
infixl 4 lessThan as <
infixl 4 greaterThan as >
infixl 4 greaterThanOrEq as >=
-------------------- Data Types -----------------------------------------------------------
data Maybe a = Nothing | Just a
data Either a b = Left a | Right b
data Ordering = LT | GT | EQ
-------------------- Type Classes ---------------------------------------------------------
class Eq a where
eq :: a -> a -> Boolean
infix 1 eq as ==
-- class Ord a where (would lead to same results in our cases)
class Eq a <= Ord a where
compare :: a -> a -> Ordering
class Show a where
show :: a -> String
-------------------- Type Classes Instances -----------------------------------------------
----------
-- Show --
----------
instance showUnit :: Show Unit where
show _ = "unit"
instance showBoolean :: Show Boolean where
show false = "false"
show true = "true"
instance showInt :: Show Int where
show = showIntImpl
instance showString :: Show String where
show = showStringImpl
instance showMaybe :: Show a => Show (Maybe a) where
show Nothing = "Nothing"
show (Just a) = "(Just " <> show a <> ")"
instance showEither :: (Show a, Show b) => Show (Either a b) where
show (Left a) = "(Left " <> show a <> ")"
show (Right b) = "(Right " <> show b <> ")"
--------
-- Eq --
--------
instance eqUnit :: Eq Unit where
eq _ _ = true
instance eqInt :: Eq Int where
eq = eqIntImpl
instance eqMaybe :: Eq a => Eq (Maybe a) where
eq Nothing Nothing = true
eq (Just a1) (Just a2) = a1 == a2
eq _ _ = false
instance eqEither :: (Eq a, Eq b) => Eq (Either a b) where
eq (Left a1) (Left a2) = a1 == a2
eq (Right b1) (Right b2) = b1 == b2
eq _ _ = false
---------
-- Ord --
---------
instance ordInt :: Ord Int where
compare = ordIntImpl LT EQ GT
instance ordMaybe :: Ord a => Ord (Maybe a) where
compare Nothing Nothing = EQ
compare Nothing _ = LT
compare _ Nothing = GT
compare (Just a) (Just b) = compare a b
instance ordEither :: (Ord a, Ord b) => Ord (Either a b) where
compare (Left a1) (Left a2) = compare a1 a2
compare (Right b1) (Right b2) = compare b1 b2
compare (Left _) _ = LT
compare (Right _) _ = GT
-------------------- Tests ----------------------------------------------------------------
test :: Effect Unit
test = do
log "Uncomment each line. IMPLEMENT missing functions BY HAND !!! No further imports!"
log $ show $ Just 5 == Just 5 -- true
log $ show $ Just 5 == Just 2 -- false
log $ show $ Just 5 == Nothing -- false
log $ show $ Nothing == Just 5 -- false
log $ show $ Nothing == (Nothing :: Maybe Unit) -- true
log $ show $ (Left "left" :: Either String Unit) -- (Left "left")
log $ show $ (Right (Just 42) :: Either Unit (Maybe Int)) -- (Right (Just 42))
log $ show $ Just 1 < Just 5 -- true
log $ show $ Just 5 <= Just 5 -- true
log $ show $ Just 5 > Just 10 -- false
log $ show $ Just 10 >= Just 10 -- true
log $ show $ Just 99 > Nothing -- true
log $ show $ Just 99 < Nothing -- false
log $ show $ Just "abc" -- (Just "abc")
log $ show $ (Nothing :: Maybe Unit) -- Nothing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment