2017-11-23 11 views
0

첫 번째 줄에 유형 주석을 추가해야하는 이유는 무엇입니까? c.get[List[String]]("primary-group")flatMap 이후에 Decoder.Result[List[String]]이며 최상위 유형을 유지하고 Decoder.Result[String]이어야하며 [DecodingFailure, String]으로 변경됩니다. 왜? 문제가 그것이 dependent type입니까? : Decoder.Result[String없이flatMap을 사용한 유형 해상도

case class JWTPayload(primaryGroup: Group, groupMember: List[Group], name: String, pid: String) 

    implicit val jwtPayloadDecoder: Decoder[JWTPayload] = Decoder.instance(c => 
    (
     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 
    ) 
) 

나는이 전체 답변을하지 않습니다하지만 난 그게 몇 가지 통찰력을 제공 할 것입니다 희망

Error:(43, 7) value map4 is not a member of (scala.util.Either[io.circe.DecodingFailure,String], io.circe.Decoder.Result[List[String]], io.circe.Decoder.Result[String], io.circe.Decoder.Result[String]) 
possible cause: maybe a semicolon is missing before `value map4'? 
    ).map4(

감사

답변

1

를 얻을. 여기서 중요한 부분은 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하고

  1. 가 일치한다 FunctorCartesian 내장 객체

  2. 그것이 튜플 다른 3 개 필드에 이용되는 펑 유형과 일치 것이다 (실제로 cats.instances.AllInstancescats.instances.EitherInstances 형질 통해 cats.implicits 개체에 의해 제공되는) (즉, Decoder.Result[_]).

그래서 나는 일반적인-배치이이 문제가 map4이 암시 옵스 - 클래스와 기본 유형이 Either 사실을 통해 4 튜플에 추가된다는 사실의 조합의 결과라고 생각합니다 단순한 Functor이 아닌 결과 [문자열] = 오른쪽 ("123") //에게 내가 작성하지 : 나는 유형의 결과가있는 경우 나 [A] = 어느 [DecodingFailure, A] 발 것을

+0

이상한 행동 입력 그것도는 [DecodingFailure, 지능] 브로 defaultTypeInference = a.map (있는 Integer.parseInt) // [지능] 브로 coercedToBeResult 결과로 강제 : 결과 [지능] = a.map (있는 Integer.parseInt)를 이 경우 flatMap의지도가 ​​결과 유형을 유지하지 않는 이유는 무엇입니까? 이 유형의 별칭이 아니라는 것을 알지만 어쨌든 – user1698641

+0

@ user1698641, 나는 당신의 요점을 잘 모르겠다. 세 번째 줄을'map.'처럼'c.get [String] ("name")과 같은 것으로 바꾸면.map (x => x + x)'이면 명시적인 타입 힌트'Decoder.Result [String]'을 제공하지 않으면 컴파일이 중단됩니다. 이 시나리오의 문제점은 'flatMap'을 할 때 유형이 손실되지 않는다는 것입니다. 'Result [A]'와'DecodingFailure, A '는 실제로 같고 Scala 컴파일러는 그것을 알고 있습니다. 이 문제는'_ [_, _] 타입 중 Decoder.Result [_] 로의이 사소한 ** _ split _ **가 손실되고 Scala 컴파일러가 스스로 그것을 다시 만들만큼 똑똑하지 않다는 것입니다 . – SergGr