Sorry if I use the wrong name for things. My question comes from comparing the syntax of Scala and Haskell. 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 could 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 types of classes, one for each implementation. In Scala, if both implementations are implicit within the scope and have the same priority, this will result in a compilation error. We can simply manually transfer 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 that are Monoid, how to choose which implementation to use?