बीजगणित में, जैसा कि रोजमर्रा की अवधारणा के गठन में होता है, कुछ आवश्यक विशेषताओं द्वारा चीजों को समूहीकृत करके और उनकी विशिष्ट अन्य विशेषताओं को छोड़ कर सार का गठन किया जाता है। अमूर्तता को एक ही प्रतीक या शब्द के तहत एकजुट किया जाता है जो समानता को दर्शाता है। हम कहते हैं कि हम मतभेदों पर अमूर्त हैं , लेकिन वास्तव में इसका मतलब है कि हम समानता द्वारा एकीकृत कर रहे हैं।
उदाहरण के लिए, एक प्रोग्राम है जो संख्याओं का योग लेता है पर विचार करें 1
, 2
और 3
:
val sumOfOneTwoThree = 1 + 2 + 3
यह कार्यक्रम बहुत दिलचस्प नहीं है, क्योंकि यह बहुत सार नहीं है। हम एक ही प्रतीक के तहत संख्या की सभी सूचियों को एकीकृत करके, हमारे द्वारा संक्षेपित संख्याओं पर सार कर सकते हैं ns
:
def sumOf(ns: List[Int]) = ns.foldLeft(0)(_ + _)
और हम विशेष रूप से परवाह नहीं करते हैं कि यह एक सूची है या तो। सूची एक विशिष्ट प्रकार का कंस्ट्रक्टर है (एक प्रकार लेता है और एक प्रकार देता है), लेकिन हम टाइप कंस्ट्रक्टर पर यह निर्दिष्ट करके सार कर सकते हैं कि हम कौन सी आवश्यक विशेषता चाहते हैं (कि इसे फोल्ड किया जा सकता है):
trait Foldable[F[_]] {
def foldl[A, B](as: F[A], z: B, f: (B, A) => B): B
}
def sumOf[F[_]](ns: F[Int])(implicit ff: Foldable[F]) =
ff.foldl(ns, 0, (x: Int, y: Int) => x + y)
और हमारे पास किसी भी अन्य चीज के Foldable
लिए निहित उदाहरण List
हो सकते हैं।
implicit val listFoldable = new Foldable[List] {
def foldl[A, B](as: List[A], z: B, f: (B, A) => B) = as.foldLeft(z)(f)
}
val sumOfOneTwoThree = sumOf(List(1,2,3))
क्या अधिक है, हम ऑपरेशन और ऑपरेंड्स के प्रकार दोनों पर अमूर्त कर सकते हैं :
trait Monoid[M] {
def zero: M
def add(m1: M, m2: M): M
}
trait Foldable[F[_]] {
def foldl[A, B](as: F[A], z: B, f: (B, A) => B): B
def foldMap[A, B](as: F[A], f: A => B)(implicit m: Monoid[B]): B =
foldl(as, m.zero, (b: B, a: A) => m.add(b, f(a)))
}
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
अब हमारे पास कुछ सामान्य है। विधि mapReduce
किसी भी F[A]
दिए को मोड़ देगी जो हम साबित कर सकते हैं कि F
वह तह है और वह A
एक मोनॉयड है या एक में मैप किया जा सकता है। उदाहरण के लिए:
case class Sum(value: Int)
case class Product(value: Int)
implicit val sumMonoid = new Monoid[Sum] {
def zero = Sum(0)
def add(a: Sum, b: Sum) = Sum(a.value + b.value)
}
implicit val productMonoid = new Monoid[Product] {
def zero = Product(1)
def add(a: Product, b: Product) = Product(a.value * b.value)
}
val sumOf123 = mapReduce(List(1,2,3), Sum)
val productOf456 = mapReduce(List(4,5,6), Product)
हम monoids और foldables पर अमूर्त है ।