5

私はscalazを試しています。アプリケーションコードでコードを書いてみました。私はこのようなコードを書きました:

val max: Option[Int] = (a |@| b) { math.max(_, _) }

私はこのコードがあまり好きではありませんでした。Haskellスタイルに近いコードを作成したいと思います。次のようになります。

val max: Option[Int] = { math.max(_, _) } <$> a <*> b

これは可能ですか。そして、なぜscalazはそれをこのように実装しなかったのですか?

4

2 に答える 2

7

Scala の型推論は、Haskell よりもはるかに制限されています (JVM が原因の 1 つである識別子のオーバーロード)。推論は左から右に流れ、関数の引数の型は前のコンテキストから推測できます (定義の場所で、引数の型が A の関数が期待される場合)。意味。Scalaz 構文は、引数の型を利用可能にします。それを逆にすると、ほとんどの場合、関数の引数の型を書く必要があります。

{math.max(_: Int, _: Int) } <$> a <*> b
于 2012-07-16T10:21:48.937 に答える
4

もう少し冗長にしたい場合は、Haskell バージョンを Scala に直接変換できます

import scalaz._, Scalaz._

val a = Option(1)
val b = Option(2)
val f: Int => Int => Int = x => math.max(x, _)

val c = b <*> (a map f)

または、ワンライナーとして:

val c = 2.some <*> 1.some.map(x => math.max(x, _: Int))

または:

val c = 2.some <*> (1.some map (math.max _).curried)

これらは中置演算子ではなくメソッド呼び出しであるため、順序が逆になっていますが、本質的には と同じですmax <$> a <*> b: 最初の項目に関数をマップし、その結果を 2 番目の項目に適用します。

于 2012-07-16T10:58:44.577 に答える