[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.자신을 인용 :
자신을 인용 :
첫 번째 단락에 비트를 확장하려면 : 때때로 당신은 모나드와 실용적 코드 사이의 선택의 여지가 없어. 당신이 모델에 (그리고 모나드 인스턴스를 가질 수 없습니다) 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.펑은 카테고리 리프팅 연산이다.
펑은 카테고리 리프팅 연산이다.
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))
실용적 펑은 해제 기능 특수 값 (카테고리의 값)을 적용하는 펑이다.
from https://stackoverflow.com/questions/19880207/when-and-why-should-one-use-applicative-functors-in-scala by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라 모음으로 자바 컬렉션을 변환 (0) | 2019.11.08 |
---|---|
[SCALA] 선물과 스칼라의 "에 대한 이해" (0) | 2019.11.08 |
[SCALA] 어떻게 미래를위한 미세 조정 스레드 풀을 구성하는 방법? (0) | 2019.11.07 |
[SCALA] 스칼라 : 목록 [미래] 미래 [목록]에 실패 미래를 무시 (0) | 2019.11.07 |
[SCALA] 이와 같은 재 시도-수 호출을 구현하는 스칼라 방법은 무엇입니까? (0) | 2019.11.07 |