복붙노트

[SCALA] 언제, 왜 하나는 스칼라에서 실용적 펑터를 사용한다

SCALA

언제, 왜 하나는 스칼라에서 실용적 펑터를 사용한다

나는 다음과 같이 모나드는 스칼라 표현 될 수 있다는 것을 알고 :

trait Monad[F[_]] {
  def flatMap[A, B](f: A => F[B]): F[A] => F[B]
}

유용 왜 내가 참조하십시오. 예를 들어, 두 가지 기능을 제공 :

getUserById(userId: Int): Option[User] = ...
getPhone(user: User): Option[Phone] = ...

나는 getPhoneByUserId (userId를 : INT) 쓰기 기능을 쉽게 할 수 있습니다 옵션 보낸 모나드이다 :

def getPhoneByUserId(userId: Int): Option[Phone] = 
  getUserById(userId).flatMap(user => getPhone(user))

...

지금은 스칼라에서 실용적은 Functor 참조 :

trait Applicative[F[_]] {
  def apply[A, B](f: F[A => B]): F[A] => F[B]
}

내가 모나드 대신 사용한다 때 나는 궁금하다. 나는 두 옵션을 생각하고 목록 Applicatives 있습니다. 당신은 옵션과 목록으로 적용하고 내가 대신 flatMap의를 사용해야하는 이유를 설명 사용하는 간단한 예제를 줄 수 있을까?

해결법

  1. ==============================

    1.자신을 인용 :

    자신을 인용 :

    첫 번째 단락에 비트를 확장하려면 : 때때로 당신은 모나드와 실용적 코드 사이의 선택의 여지가 없어. 당신이 모델에 (그리고 모나드 인스턴스를 가질 수 없습니다) Scalaz의 유효성 검사를 사용하려는 이유에 대한 설명은 그 대답의 나머지 부분을 참조하십시오 확인, 검증.

    최적화 점에 관하여 :이 스칼라 또는 Scalaz 일반적으로 관련이 전에 동안 아마있을 거 야하지만, 예를 하스켈의 Data.Binary에 대한 설명서를 참조하십시오 :

    실용적 코드를 작성하는 것은 비슷한 모나드 코드가 당신에게 커밋 것이라고 계산-주장 사이의 종속성에 대한 불필요한 주장을 피할 수 있습니다. 충분하게 스마트 라이브러리 또는이 사실의 원칙 걸릴 우위 컴파일러 수 있습니다.

    이 아이디어를 조금 더 콘크리트를 만들려면 다음 모나드 코드를 고려하십시오

    case class Foo(s: Symbol, n: Int)
    
    val maybeFoo = for {
      s <- maybeComputeS(whatever)
      n <- maybeComputeN(whatever)
    } yield Foo(s, n)
    

    더 많거나 적은 다음과 같은에 대한-이해 desugars :

    val maybeFoo = maybeComputeS(whatever).flatMap(
      s => maybeComputeN(whatever).map(n => Foo(s, n))
    )
    

    우리는 maybeComputeN이 (무엇이든) (뒤에서 일부 변경 가능한 상태를 변경하지 않습니다이 잘 행동하는 방법을 가정)에의 의존하지 않는다는 것을 알고 있지만, 컴파일러가 나던-에서의 관점은 이전의를 알 필요가 그것은 N을 계산하기 시작할 수있다.

    (Scalaz 사용)과 실용적 버전은 다음과 같습니다 :

    val maybeFoo = (maybeComputeS(whatever) |@| maybeComputeN(whatever))(Foo(_, _))
    

    여기에서 우리는 명시 적으로 두 개의 계산 사이에 의존성이 없다는 것을 주장하고있다.

    (그리고 네,이 | @ | 문법은 꽤 일부 논의와 대안이 블로그 게시물을 끔찍한-참조하십시오.)

    마지막 포인트는하지만, 정말 가장 중요하다. 문제를 해결할 가장 강력한 도구를 따기 대단히 강력한 원칙이다. 때때로 당신은 정말 당신의 getPhoneByUserId 방법에 조성 모나드를 필요로 예를 들어-하지만 자주하지 않습니다.

    그것은 하스켈과 스칼라 모두 현재 실용적 펑 작업에 비해 (구문 등) 훨씬 더 편리 모나드 작업을 만들지 만, 이것은 주로 역사적 사고의 문제이며, 관용구 브래킷 등의 개발이 바로 한 단계 것을 부끄러운 방향.

  2. ==============================

    2.펑은 카테고리 리프팅 연산이다.

    펑은 카테고리 리프팅 연산이다.

    trait Functor[C[_]] {
      def map[A, B](f : A => B): C[A] => C[B]
    }
    

    그리고 그것은 하나 개의 변수의 기능에 대해 완벽하게 작동합니다.

    val f = (x : Int) => x + 1
    

    그러나 2의 기능에 대한 더 많은 범주에 들기 후, 우리는 서명을 다음 있습니다 :

    val g = (x: Int) => (y: Int) => x + y
    Option(5) map g // Option[Int => Int]
    

    그리고 그것은 실용적 펑터의 서명입니다. aplicative 펑 필요 - 및 함수 g로 다음 값을 적용한다.

    trait Applicative[F[_]] {
      def apply[A, B](f: F[A => B]): F[A] => F[B]
    } 
    

    그리고 마지막으로:

    (Applicative[Option] apply (Functor[Option] map g)(Option(5)))(Option(10))
    

    실용적 펑은 해제 기능 특수 값 (카테고리의 값)을 적용하는 펑이다.

  3. from https://stackoverflow.com/questions/19880207/when-and-why-should-one-use-applicative-functors-in-scala by cc-by-sa and MIT license