Apologies if I am using the wrong name for things. My question comes from contrasting Scala and Haskell syntax. Consider:
class Monoid a where
mempty :: a
mappend :: a -> a -> a
instance Monoid Int where
mempty = 0
mappend a b = a + b
sigma :: (Monoid a) => Int -> Int -> (Int -> Int) -> (Int -> a) -> a
sigma a b inc comp =
if a > b then mempty else mappend (comp a) (sigma (inc a) b inc comp)
In Scala it would probably be something like:
trait Monoid[A] {
def mempty: A
def mappend(a1: A, a2: A): A
}
class IntMonoid extends Monoid[Int] {
def mempty = 0
def mappend(a: Int, b: Int) = a + b
}
def sigma[A](a: Int, b: Int, inc: Int => Int, comp: Int => a)
(implicit m: Monoid[A]): A =
if (a > b) m.mempty else m.append(comp(a), sigma(inc(a), b, inc, comp))
Now, Int can be a Monoid with 0 and addition, but also with 1 and multiplication, so we can provide 2 type classes, one for each implementation. In Scala, if both implementations are implicit within the scope and have the same priority, this will cause a compile error. We can simple manually pass the correct instance in this case, and the error will be resolved.
What is the Haskell equivalent for this situation? If there are two instances of Int being Monoid, how can one choose which implementation to use?
Haskell simply has two newtype wrapper for any type that actually is an instance of Num
(includes Int
type) typeclass: Sum
and Product
. So, Sum
is a monoid under addition and Product
type is a monoid under multiplication. Taken from actual source:
newtype Sum a = Sum { getSum :: a }
deriving (Eq, Ord, Read, Show, Bounded, Generic, Generic1, Num)
instance Num a => Monoid (Sum a) where
mempty = Sum 0
Sum x `mappend` Sum y = Sum (x + y)
newtype Product a = Product { getProduct :: a }
deriving (Eq, Ord, Read, Show, Bounded, Generic, Generic1, Num)
instance Num a => Monoid (Product a) where
mempty = Product 1
Product x `mappend` Product y = Product (x * y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With