Signature
trait MySemigroupal[F[_]] {
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}
Example
import cats.instances.future._
implicit val ec: ExecutionContext = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(0))
val aTupledFuture = Semigroupal[Future].product(Future("the meaning of life"), Future(45))
// -> Future(("the meaning of life", 45))
import cats.instances.list._
val aTupledList = Semigroupal[List].product(List(1,2), List("a", "b"))
// --> List((1,a), (1,b), (2,a), (2,b))
Monad와 연관성
- Monad extends Semigroupals
- Monad의 요소로 Semigroupls의 product을 구현할 수 있다.
trait CustomMonad[M[_]] {
def pure[A](value: A): M[A]
def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]
def map[A, B](ma: M[A])(f: A => B): M[B] =
flatMap(ma)(x => pure(f(x)))
// ----
def product[A, B](fa: M[A], fb: M[B]): M[(A, B)] =
flatMap(fa)(a => map(fb)(b => (a, b)))
}
Use Case
- Monad는 short circuit이 발생하는 반면, Semigroup을 활용하면 모든 데이터를 하나로 모을 수 있다.
import cats.data.Validated
type ErrorsOr[T] = Validated[List[String], T]
val validatedSemigroupal = Semigroupal[ErrorsOr]
val invalidsCombination = validatedSemigroupal.product(
Validated.invalid(List("Error A", "Error B")),
Validated.invalid(List("Error C"))
)
// --> Invalid(List(Error A, Error B, Error C))
'Tech > Scala' 카테고리의 다른 글
함수형 프로그래밍 Type Class : FlatMap and Monad (0) | 2024.02.24 |
---|---|
함수형 프로그래밍 Type Classes: Applicative, Apply (0) | 2024.02.18 |
함수형 프로그래밍의 시작점(?), Free Monad in Scala (0) | 2023.10.13 |
함수형 프로그래밍의 Monad 개념 정리 (in Scala) (0) | 2022.12.20 |
Scala Slick 괴문법 <>의 원리를 찾아서 (0) | 2022.01.14 |