I'm trying to convert an Haskell Semigroup
to Scala. The Haskell code works fine but I can't write it in Scala
Haskell:
import Data.Semigroup
newtype Combine a b = Combine { unCombine :: (a -> b) }
instance Semigroup b => Semigroup (Combine a b) where
Combine f <> Combine g = Combine (f <> g)
f = Combine $ \n -> Sum (n + 1)
g = Combine $ \n -> Sum (n - 1)
print (unCombine (f <> g) $ 0) -- Sum 0
print (unCombine (f <> g) $ 10) -- Sum 20
Scala code
import cats.Semigroup
import cats.instances.all._
trait Combine[A, B] {
def unCombine(a: A): B
}
val f = new Combine[Int, Int] {
override def unCombine(n: Int): Int = n + 1
}
val g = new Combine[Int, Int] {
override def unCombine(n: Int): Int = n - 1
}
implicit val mySemigroup: Semigroup[Combine[Int, Int]] = new Semigroup[Combine[Int, Int]] {
def combine(x: Combine[Int, Int], y: Combine[Int, Int]): Combine[Int, Int] = (x,y) match {
// ???
}
}
In addition to the answer by @KartikSabharwal, because both
Semigroup
andCombine
are functional interfaces, since Scala 2.12 you can define the specific case like this:And the generic case, which @KartikSabharwal has mentioned would look like this in Scala 2.12:
And like this in Scala 2.11: