বীজগণিতকালে, যেমন প্রতিদিনের ধারণা গঠনের মতো বিমূর্ততা কিছু প্রয়োজনীয় বৈশিষ্ট্য দ্বারা জিনিসগুলিকে গোষ্ঠীকরণ এবং তাদের নির্দিষ্ট অন্যান্য বৈশিষ্ট্যগুলি বাদ দিয়ে তৈরি হয়। বিমূর্ততাটি একটি একক প্রতীক বা শব্দের অধীনে একীভূত হয়েছে যা মিলগুলি বোঝায়। আমরা বলি যে আমরা পার্থক্যগুলিকে বিমূর্ত করি , তবে এর সত্যিকার অর্থে আমরা মিলগুলি দ্বারা সংহত করছি gra
উদাহরণস্বরূপ, একটি প্রোগ্রাম যা সংখ্যার যোগফল লাগে বিবেচনা 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)
আমরা মনোয়েড এবং ফোল্ডেবলগুলি বিমূর্ত করে ফেলেছি।