2017-09-20 16 views
1

을 감안할 때 : 그것은 x을 변경하는 것이 합리적이다, 그 결과Kleisli의 다른 입력 유형에 '다음'이 있습니까?

scala> x >> y 
<console>:21: error: type mismatch; 
found : scalaz.Kleisli[scalaz.concurrent.Task,String,Unit] 
required: scalaz.Kleisli[scalaz.concurrent.Task,Int,?] 
     x >> y 
      ^

Kleisli[Task, Int, Boolean]에서 y의 종류와 Kleisli[Task, AppConfig, Boolean]-Kleisli[Task, String, Boolean] :

import scalaz._, Scalaz._ 
import scalaz.concurrent.Task 

case class AppConfig(x: Int, y: String) 

val x = Kleisli[Task, Int, Boolean] { 
    case i: Int => if (i === 42) Task.now(true) else Task.now(false) 
} 

val y = Kleisli[Task, String, Unit] { 
    case s: String => Task.delay { println(s"$s was here") } 
} 

I 실패로 인해 컴파일에 x >> y를 호출 할 수 없습니다?

그렇지 않은 경우 더 나은 대안과 근거를 제시하십시오.

답변

2

나는 당신을 위해 무엇을 찾고있는 것은 당신에게 Kleisli[Task, (Int, String), (Boolean, Unit)]을 줄 것이다

x *** y 

생각합니다.

***Arrow 구문에서 유래하고 (또는 >>=>> 순차적 조성물 대조적으로) 병렬 조성물을 의미한다.

1

Scalaz에서 Kleisli[M, A, B]은 Scala 함수 A => M[B]으로 해석 될 수 있기 때문에이 경우에 사용되는 기본 제공 판독기 모나드 인스턴스가 있습니다. 리더 모나드는 고정 유형 R에서 읽는 함수 R => M[A]에 정의됩니다. 따라서 입력 유형이 Kleisli 일 때 사용하려면 일치해야합니다. 그렇지 않은 경우입니다. Kleisli 구성 >=>도 사용할 수 없습니다. 첫 번째 Kleisli (B 서명)의 결과 유형이 두 번째 입력 유형 A과 일치해야합니다. 당신은 인수를 제공하고 Task 수준까지 이동할 수 있습니다

import scalaz.syntax.arrow._ // if you're not importing whole Scalaz 
import Function.const 
(x *** y).map(const()) // use map to ignore result 
: 다른 대답에 명시된 바와 같이, 당신은 Kleisli 수준에서 유지하려는 경우

x(42) >> y("abc") 

또한, 병렬 화살표 구성을 사용할 수 있습니다

결국에는 나중에 인수를 제공해야 함을 의미합니다.