Ad-Hoc Polymorphism; Overloading
-- OCaml be like:
-- +
incrementInt :: Int -> Int
incrementInt n = n + 1
-- +.
incrementFloat :: Float -> Float
incrementFloat n = n + 1
-- Haskell be like:
increment :: Num a => a -> a
increment n = n + 1
-- >>> increment 1
-- 2
-- >>> increment 1.1
-- 2.1
λ> :i Num
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
instance Num Int -- Defined in ‘GHC.Num’
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Word -- Defined in ‘GHC.Num’
data Nat = Zero | Succ Nat
deriving stock (Show)
instance Num Nat where
-- Add
(+) :: Nat -> Nat -> Nat
Zero + b = b
(Succ a) + b = Succ (a + b)
-- Mul
(*) :: Nat -> Nat -> Nat
Zero * _ = Zero
(Succ a) * b = b + (a * b)
-- Sub
(-) :: Nat -> Nat -> Nat
Zero - _ = Zero
m - Zero = m
(Succ m) - (Succ n) = m - n
-- Abs
abs :: Nat -> Nat
abs n = n
-- Signum
signum :: Nat -> Nat
signum Zero = Zero
signum (Succ _) = Succ Zero
-- Conversion
fromInteger :: Integer -> Nat
fromInteger n
| n <= 0 = Zero
| otherwise = Succ (fromInteger (n - 1))
zero, one, two, three :: Nat
zero = Zero
one = Succ zero
two = Succ one
three = Succ two
λ> zero + one
Succ Zero
λ> one + two
Succ (Succ (Succ Zero))
Eq
) - finding elementsOrd
) - sorting elementsclass Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
instance Eq Nat where
(==) :: Nat -> Nat -> Bool
Zero == Zero = True
Zero == _ = False
_ == Zero = False
(Succ m) == (Succ n) = m == n
λ> zero == zero
True
λ> one == zero
False
-- `elem` checks if the element is in list
-- elem :: (Foldable t, Eq a) => a -> t a -> Bool
λ> elem one [zero, one, two]
True
λ> elem three [zero, one, two]
False
λ> elem zero (Just zero)
True
λ> elem zero (Just one)
False
λ> elem zero Nothing
False
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
instance Ord Nat where
compare Zero Zero = EQ
compare Zero _ = LT
compare _ Zero = GT
compare (Succ m) (Succ n) = compare m n
λ> zero > one
False
λ> zero < one
True
import Data.List (sort)
λ> sort [one, zero]
[Zero,Succ Zero]