9

私は以前に出会ったhaskellの例をscalazに変換しようとしていました。元の例は次のとおりです。

("Answer to the ", (*)) <*> ("Ultimate Question of ", 6) <*> ("Life, the Universe, and Everything", 7)

私が理解できる限り、これはこのインスタンスを使用します。

文字通りscalazに変換されません:

scala> ("Answer to the ", ((_: Int) * (_: Int)) curried) |@| ("Ultimate Question of ", 6) |@| ("Life, the Universe, and Everything", 7) tupled
res37: (java.lang.String, (Int => (Int => Int), Int, Int)) = (Answer to the Ultimate Question of Life, the Universe, and Everything,(<function1>,6,7))

しかし、私はインスタンスを探しました、そしてそれはそこにあるようです(私が理解できる限り、再び)。

それで、問題は、なぜそれがこのように機能しないのかということです。または、何を見逃したか、正しく取得できませんでしたか?

4

1 に答える 1

5

ScalazのControl.Applicative'sに相当するものは、<*>と呼ばれる<*>こともありますが、紛らわしいことにその引数を逆の順序で取ります。したがって、次のように機能します。

val times = ((_: Int) * (_: Int)) curried
val a = "Answer to the "
val b = "Ultimate Question of "
val c = "Life, the Universe, and Everything"

(c, 7) <*> ((b, 6) <*> (a, times))

または、あなたのコメントに応えて私が指摘したように、あなたが固執したいのであれば、あなたは以下を使うことができます|@|

(a -> times |@| b -> 6 |@| c -> 7)(_ apply _ apply _)

<*>たとえそれが後ろ向きに感じても、私は個人的にそのバージョンを好みます。


何が起こっているのかをもう少し詳しく説明できます。まず第一に、ここの完全な力は必要ありませんApplicative—<code>Applyで十分です。Applyタプルのインスタンスは、次を使用して取得できimplicitlyます。

scala> val ai = implicitly[Apply[({type λ[α]=(String, α)})#λ]]
ai: scalaz.Apply[[α](java.lang.String, α)] = scalaz.Applys$$anon$2@3863f03a

これで、最初のタプルを2番目のタプルに適用できます。

scala> :t ai(a -> times, b -> 6)
(java.lang.String, Int => Int)

そして3番目の結果:

scala> :t ai(ai(a -> times, b -> 6), c -> 7)
(java.lang.String, Int)

これが私たちが望むものです:

scala> ai(ai(a -> times, b -> 6), c -> 7)._1
res0: java.lang.String = Answer to the Ultimate Question of Life, the Universe, and Everything

scala> ai(ai(a -> times, b -> 6), c -> 7)._2
res1: Int = 42

<*>メソッドは、MAこれをもう少しうまくまとめます。

于 2012-06-07T19:44:57.377 に答える