scala – Haskell如何区分不同的可能类型类实例

如果我使用错误名称,请道歉.我的问题来自对比 Scala和Haskell语法.考虑:

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)

在Scala中它可能是这样的:

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))

现在,Int可以是一个带有0和加法的Monoid,但也有1和乘法,所以我们可以提供2个类型,每个实现一个.在Scala中,如果两个实现都隐含在范围内并具有相同的优先级,则会导致编译错误.在这种情况下,我们可以简单地手动传递正确的实例,并且将解决错误.

对于这种情况,Haskell的等价物是什么?如果有两个Int实例是Monoid,那么如何选择使用哪个实现呢?

解决方法

Haskell对于任何实际上都是Num实例(包括Int类型)类型类:Sum和Product的类型只有两个newtype包装器.因此,Sum是一个加成的monoid,Product类型是乘法下的monoid.取自实际来源:

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,Num)

instance Num a => Monoid (Product a) where
        mempty = Product 1
        Product x `mappend` Product y = Product (x * y)

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...