대수 구조

11324 단어 functionalscala
개발자가 함수형 프로그래밍으로 작업할 수 있으려면 마스터해야 하는 몇 가지 개념이 있습니다.

에 더하여, (ADT)와 대수적 구조라는 두 가지 매우 중요한 주요 아이디어가 있습니다. 이 포스트에서 우리는 몇 가지 대수적 구조를 살펴보고 있습니다.

펑터



Functor는 가장 단순한 대수 구조입니다. 데이터 또는 데이터에 대한 작업과 성공적인 결과를 매핑할 수 있는 래퍼입니다.

Scala의 기본 펑터 예제는 scala.util.Try 입니다.

Try(1 / x)
  .map(e => e*e)
  .map(1 - _)
  .map(_.toString) match {
    case Success(value) => s"the result is $value"
    case Failure(exc)   => s"it raised an exception: $exc"
  }

Seq/List , Option , Either 등과 같은 대부분의 Scala 기본 래퍼도 펑터입니다.

모나드



Haskell 의 모나드는 사람들을 공포에 떨게 했지만 펑터 접근 방식의 변형일 뿐입니다.

모나드는 결과를 평면적으로 매핑하고 부작용을 설명할 수 있는 데이터 또는 데이터를 둘러싼 래퍼입니다.

첫 번째 모나드 예제는 Seq 입니다.

Seq(1, 2, 3)
  .flapMap(e => Seq(e * 2))
  .flatMap(e => if (e == 2) Nil else Seq(e))
  .flatMap(e => if (e == 4) Seq(4, 5) else Seq(e))


결과는 Seq(4, 5, 6) 입니다. flatMap 메서드는 모나드의 주요 리소스입니다.
Seq도 펑터이기 때문에 첫 번째 flatMapmap로 바꿀 수 있으며 filter보다 표현력이 뛰어난 flatMap 메서드가 있습니다.

Seq(1, 2, 3)
  .map(_ * 2)
  .filter(_ != 2)
  .flatMap(e => if (e == 4) Seq(4, 5) else Seq(e))


결과는 동일합니다. List , Option , Try , Either 등도 모나드입니다.

가장 잘 알려진 모나드는 Haskell's IO 입니다. IO 모나드는 I/O 부작용이 어떻게 발생하는지 설명합니다.

예를 들어:

greetings :: IO ()
greetings = printStrLn "Hello, World!"

greetings 함수는 표준 출력에 쓰기를 트리거할 수 있는 IO 모나드를 멱등적으로 반환합니다.

모노이드



모노이드는 해당 작업 및 유형에 대한 작업 및 단위 인스턴스를 제공하는 구조입니다.

모노이드 정의는 다음과 같습니다.

trait Monoid[A] {
  def add(a: A, b: A): A
  def unit[A]: A
}


예를 들어 정수 및 문자열 시퀀스를 처리하기 위해 두 개의 모노이드를 정의해 보겠습니다.

implicit object IntMonoid extends Monoid[Int] {
  def add(a: Int, b: Int): Int = a + b
  def unit: Int = 0
}

implicit object StringMonoid extends Monoid[String] {
  def add(a: String, b: String): String = a concat b
  def unit: String = ""
}


이 두 가지 모노이드를 정의하면 정수 또는 문자열 시퀀스를 줄일 수 있는 함수를 코딩할 수 있습니다.

def reduce[A](xs: Seq[A])(implicit ev: Monoid[A]): A =
  if (xs.isEmpty) ev.unit
  else ev.add(xs.head, reduce(xs.tail))


다음과 같이 작동합니다.

reduce(Seq(1, 2, 3)) // returns 6
reduce(Seq("Hello", ", ", "World", "!")) // returns "Hello, World!"

reduce 함수가 다른 유형과 제대로 작동하려면 DoubleMonoid 와 같이 다른 유형의 암시적 모노이드를 제공하는 것으로 충분하며 reduce 함수를 변경할 필요가 없습니다.

적용, 적용, 세미링, 격자 등



다른 대수적 구조는 대부분 우리가 방금 겪은 이 세 가지의 변형일 뿐입니다. 에서 몇 가지 정의를 찾을 수 있습니다.


Kodumaro의 원본 게시물 .

좋은 웹페이지 즐겨찾기