Home > Back-end >  Is the Haskell operator * a combination of operators?
Is the Haskell operator * a combination of operators?

Time:07-14

How does Haskell's * work? Does it create a series of operators, or does it do something else?

CodePudding user response:

This is the Num type class

type  Num :: Type -> Constraint
class Num a where
  ( ) :: a -> a -> a
  (*) :: a -> a -> a
  -- .. I'm omitting the other methods

This is how Num is defined for Int (src)

instance Num Int where
  ( ) :: Int -> Int -> Int
  I# x   I# y = I# (x  # y)

  (*) :: Int -> Int -> Int
  I# x * I# y = I# (x *# y)
  -- ..

This is how it's defined for Float (src)

instance Num Float where
  ( ) :: Float -> Float -> Float
  F# x   F# y = F# (plusFloat# x y)

  (*) :: Float -> Float -> Float
  F# x   F# y = F# (timesFloat# x y)

Maybe not enlightening but you can see that (for those instances) they are defined in terms of primitive operations like ( #) or timesFloat#. If you define your own number you can define multiplication in terms of repeated addition but the operations are not fundamentally defined that way.

type N :: Type
data N = O | S N

instance Num N where
  ( ) :: N -> N -> N
  O     m = m
  S n   m = S (n   m)

  (*) :: N -> N -> N
  O   * _ = O
  S n * m = m   (n * m)

You can define a "default" multiplication function that is defined in terms of repeated additions

-- >> timesViaPlus @Int @Int 10 20
-- 200
-- >> timesViaPlus @Integer @Integer 10 20
-- 200
timesViaPlus :: Integral n => Num m => n -> m -> m
timesViaPlus n m = sum (fromIntegral n `replicate` m)

or you could specialize it to N and use it to define (*) @N.

replicateN :: N -> a -> [a]
replicateN O     _ = []
replicateN (S n) a = a : replicateN n a

timesViaPlusN :: Num n => N -> n -> n
timesViaPlusN n m = sum (n `replicateN` m)

instance Num N where
  ( ) :: N -> N -> N
  O     m = m
  S n   m = S (n   m)

  (*) :: N -> N -> N
  (*) = timesViaPlusN
  • Related