를 얻을. 여기서 중요한 부분은 map4
이 구현 된 방법입니다. 고양이 0.9부터는 cats.syntax.TupleCartesianSyntax
형질을 통해 행해졌 고, 012 튜토리얼을 cats.syntax.Tuple4CartesianOps
클래스로 감싸는 암시적인 catsSyntaxTuple4Cartesian
(cats 1.0에서는 "cartesian"이 "semigroupal"으로 변경되었습니다). 이 코드는 최대 22 개의 튜플에 대해 Boilerplate.scala에 의해 자동 생성됩니다.
implicit def catsSyntaxTuple4Cartesian[F[_], A0, A1, A2, A3](t4: Tuple4[F[A0], F[A1], F[A2], F[A3]]): Tuple4CartesianOps[F, A0, A1, A2, A3] = new Tuple4CartesianOps(t4)
private[syntax] final class Tuple4CartesianOps[F[_], A0, A1, A2, A3](t4: Tuple4[F[A0], F[A1], F[A2], F[A3]]) {
def map4[Z](f: (A0, A1, A2, A3) => Z)(implicit functor: Functor[F], cartesian: Cartesian[F]): F[Z] = Cartesian.map4(t4._1, t4._2, t4._3, t4._4)(f)
def contramap4[Z](f: Z => (A0, A1, A2, A3))(implicit contravariant: Contravariant[F], cartesian: Cartesian[F]): F[Z] = Cartesian.contramap4(t4._1, t4._2, t4._3, t4._4)(f)
def imap4[Z](f: (A0, A1, A2, A3) => Z)(g: Z => (A0, A1, A2, A3))(implicit invariant: Invariant[F], cartesian: Cartesian[F]): F[Z] = Cartesian.imap4(t4._1, t4._2, t4._3, t4._4)(f)(g)
def apWith[Z](f: F[(A0, A1, A2, A3) => Z])(implicit apply: Apply[F]): F[Z] = apply.ap4(f)(t4._1, t4._2, t4._3, t4._4)
}
참고 F[_]
(펑) 매개 변수를 입력 : 자동 생성 된 코드는 다음과 같이 보인다. 효과적으로이 코드는 각 내부 유형이 일부 유형과 동일한 펑터 인 모든 4- 튜플에 map4
메소드를 추가합니다. 후, import cats.implicits._
을 한 가정
따라서는 (부분)이 implicits 해상도는 코드가 실제로이 같은 것입니다 :
cats.implicits.catsSyntaxTuple4Cartesian[Decoder.Result, String, List[String], String, String](
c.get[List[String]]("primary-group").flatMap(l => if (l.size == 1) l.head.asRight else DecodingFailure("", c.history).asLeft): Decoder.Result[String],
c.get[List[String]]("group-member"),
c.get[String]("name"),
c.get[String]("pid")
).map4[JWTPayload](
JWTPayload
)
당신이 Decoder.Result[String]
를 지정하지 않는, 스칼라 컴파일러는 것을 얻을만큼 똑똑하지 않다 펑터 타입으로 Either[DecodingFailure, String]
분할 Either[DecodingFailure, _]
및 String
하고
가 일치한다 Functor
및 Cartesian
내장 객체
그것이 튜플 다른 3 개 필드에 이용되는 펑 유형과 일치 것이다 (실제로 cats.instances.AllInstances
및 cats.instances.EitherInstances
형질 통해 cats.implicits
개체에 의해 제공되는) (즉, Decoder.Result[_]
).
그래서 나는 일반적인-배치이이 문제가 map4
이 암시 옵스 - 클래스와 기본 유형이 Either
사실을 통해 4 튜플에 추가된다는 사실의 조합의 결과라고 생각합니다 단순한 Functor
이 아닌 결과 [문자열] = 오른쪽 ("123") //에게 내가 작성하지 : 나는 유형의 결과가있는 경우 나 [A] = 어느 [DecodingFailure, A] 발 것을
이상한 행동 입력 그것도는 [DecodingFailure, 지능] 브로 defaultTypeInference = a.map (있는 Integer.parseInt) // [지능] 브로 coercedToBeResult 결과로 강제 : 결과 [지능] = a.map (있는 Integer.parseInt)를 이 경우 flatMap의지도가 결과 유형을 유지하지 않는 이유는 무엇입니까? 이 유형의 별칭이 아니라는 것을 알지만 어쨌든 – user1698641
@ user1698641, 나는 당신의 요점을 잘 모르겠다. 세 번째 줄을'map.'처럼'c.get [String] ("name")과 같은 것으로 바꾸면.map (x => x + x)'이면 명시적인 타입 힌트'Decoder.Result [String]'을 제공하지 않으면 컴파일이 중단됩니다. 이 시나리오의 문제점은 'flatMap'을 할 때 유형이 손실되지 않는다는 것입니다. 'Result [A]'와'DecodingFailure, A '는 실제로 같고 Scala 컴파일러는 그것을 알고 있습니다. 이 문제는'_ [_, _] 타입 중 Decoder.Result [_] 로의이 사소한 ** _ split _ **가 손실되고 Scala 컴파일러가 스스로 그것을 다시 만들만큼 똑똑하지 않다는 것입니다 . – SergGr