質問

視聴後 ニック・パーティッジ氏のプレゼンテーション 導き出す上で スカラズ, で、この例を見てみましょう。これは本当に素晴らしいです。

import scalaz._
import Scalaz._
def even(x: Int) : Validation[NonEmptyList[String], Int] 
    = if (x % 2 ==0) x.success else "not even: %d".format(x).wrapNel.fail

println( even(3) <|*|> even(5) ) //prints: Failure(NonEmptyList(not even: 3, not even: 5))

私はそれが何なのかを理解しようとしていた <|*|> メソッドが実行していました。ソースコードは次のとおりです。

def <|*|>[B](b: M[B])(implicit t: Functor[M], a: Apply[M]): M[(A, B)] 
    = <**>(b, (_: A, _: B))

OK、それはかなり混乱します (!) - しかし、それは <**> このメソッドは次のように宣言されます。

def <**>[B, C](b: M[B], z: (A, B) => C)(implicit t: Functor[M], a: Apply[M]): M[C] 
    = a(t.fmap(value, z.curried), b)

そこで、いくつか質問があります。

  1. なぜこのメソッドは時間がかかるように見えるのですか 高尚なタイプ 1 つの型パラメータ (M[B])しかし、渡される可能性があります Validation (2 つの型パラメータがあります)?
  2. 構文 (_: A, _: B) 関数を定義します (A, B) => Pair[A,B] 2 番目のメソッドが期待するもの: 障害が発生した場合、Tuple2/Pair に何が起こっていますか?タプルが見当たらない!
役に立ちましたか?

解決

タイプのコンストラクタとしての型パラメータ

M は、typeパラメータのScalaz主pimps, MA, を表すタイプのコンストラクタ(通称高Kindedタイプ)のpimped値です。このコンストラクタを使って、適切なインスタンス FunctorApply, する暗黙条件の方法 <**>.

trait MA[M[_], A] {
   val value: M[A]
   def <**>[B, C](b: M[B], z: (A, B) => C)(implicit t: Functor[M], a: Apply[M]): M[C] = ...
}

うタイプのコンストラクタ?

のスカーラの言語参考:

まとめる 種類のタイプのコンストラクタは、 取型のパラメータの利回ります。サブセットの一次型と呼ばれ 値型を表す定の (初級)値です。値の種類 はコンクリートまたは抽象的である。毎 具体的な値型を表すことができ としてクラスタイプ、すなわちaタイプ 識別記号(§3.2.3)とは クラス1(§5.3)、または化合物として、タイプ (§3.2.7)の代表交差点 の種類の可能性のある精密に (§3.2.7)をさらに制限する 種類のitsmembers.抽象的価値 種を導入したタイプ パラメータ(§4.4)および抽象タイプ バインディング(§4.3).括弧内の種類 使い分類.想定していま オブジェやパッケージにも暗黙的に クラスを定義するのと同じ名前 のオブジェクトまたはパッケージですが、 を利用することができなユーザプログラム).

非値型の捕捉特性 識別子のない価値 (§3.3).例えば、タイプ コンストラクタ(§3.3.3)な の種類を指定します。しかし、 きタイプのコンストラクタへの適用 正しい型の引数で利回り に関する情報を得るため、タイプの場合 値タイプです。非値タイプ 表現を間接的にでScala.E.g.) a 方法タイプに記述される文書 下の方法に署名し、 そのものがリアルタイプでは が対応する機能 タイプ(§3.3.1).タイプコンストラクタ もうひとつの例としてあまり書けタイプ スワップ[m[_,_],a,b]=m[b]、 ありませんの構文を書く 対応する匿名のタイプ機能 ます。

List タイプコンストラクタです。簡単に適用することができ型 Int 得値型 List[Int], できる分類を指定します。その他のタイプのコンストラクタによると、パラメータとします。

の特徴 scalaz.MA 要するので初となるtypeパラメータでなければなタイプを取るコンストラクタでシングルタイプの戻り値の型関数が値を返すタイプの構文 trait MA[M[_], A] {}.Typeパラメータ定義を記述する形状タイプのコンストラクタと呼ばれることになる。 List がはっきりしていると言われていな'* -> *.

一部申請の種類

がどのように MA ラップ価値の型 Validation[X, Y]?タイプ Validation らない (* *) -> *, ときとして渡された型の引数型のパラメータ宣言されたような M[_, _].

この暗黙的に変換 オブジェクトScalaz に変換した値の型 Validation[X, Y]MA:

object Scalaz {
    implicit def ValidationMA[A, E](v: Validation[E, A]): MA[PartialApply1Of2[Validation, E]#Apply, A] = ma[PartialApply1Of2[Validation, E]#Apply, A](v)
}

源を使用しトリックタイプの別名 PartialApply1Of2 一部のタイプのコンストラクタ Validation, 固定の種類の誤差が出るタイプの成功unapplied.

PartialApply1Of2[Validation, E]#Apply する記述として [X] => Validation[E, X].私は最近提案され、そのリンクがどのような構文をスカラが起2.9.

ると考えることとして式レベルに相当す:

def validation[A, B](a: A, b: B) = ...
def partialApply1Of2[A, B C](f: (A, B) => C, a: A): (B => C) = (b: B) => f(a, b)

ことができますの融合 Validation[String, Int]Validation[String, Boolean], では、両方のタイプのコンストラクタ [A] Validation[String, A].

応用Functors

<**> 要求されるタイプのコンストラクタ M は関連するインスタンス 適用.これを構成する応用元するように、Monadであり、構造の計算を通じて効果があります。この場合の影響であるサブ計算に失敗する(きていたの蓄積に失敗).

コンテナの Validation[NonEmptyList[String], A] ラッピ純粋な価値の型 A このためには、してきました。の <**> オペレーターでは、二effectful値には、純粋な機能と組み合わせとしての応用元インスタンスに対する容器です。

このために Option 応用元.の効果はこちらではの可能性。

val os: Option[String] = Some("a")
val oi: Option[Int] = Some(2)

val result1 = (os <**> oi) { (s: String, i: Int) => s * i }
assert(result1 == Some("aa"))

val result2 = (os <**> (None: Option[Int])) { (s: String, i: Int) => s * i }
assert(result2 == None)

場合があり、純粋な機能タイプ (String, Int) => String, は、適用effectful論争することができます。この結果に包まれと同様の効果(コンテナであれば)として論争することができます。

利用できるのと同じパターン全体の多くの容器関連付けられてい応用元.すべてのMonads自動的に応用Functorsも力をいただいておりますように、 ZipStream.

Option[A]Validation[X, A] もMonadsので、このまま使用 Bind (通称flatMap):

val result3 = oi flatMap { i => os map { s => s * i } }
val result4 = for {i <- oi; s <- os} yield s * i

Tuplingの"<|**|>`

<|**|> によく似て <**>, で提供の純粋な機能だけをTuple2から。 (_: A, _ B) は以下の表記 (a: A, b: B) => Tuple2(a, b)

以降

こちらは当社の同梱の例 応用検証.を使って若干異なる書式を利用応用元, (fa ⊛ fb ⊛ fc ⊛ fd) {(a, b, c, d) => .... }

更新:が起こっていることに失敗。

何が起きているのかをTuple2/ペアの故障の場合?

場合の計算に失敗した場合、提供機能がない。であれば、すべての計算(この場合には、引数に渡される <**>)指します。できる場合、これらを組み合わせに Success.ここはどこ論理によるものか。この定義に Apply インスタンス [A] Validation[X, A].また、Xタイプが必要 Semigroup ちらの戦略を組み合わせ個人誤差があり、各タイプ X, く、集計の誤差と同じタイプです。を選択する String としてエラータイプの Semigroup[String] concatenatesの文字列を選択する NonEmptyList[String], のエラーからの各段階ごとに連な NonEmptyList 誤差は生じません。この連結が起こる場合は、以下の二つの Failures 組み合わせを使用し、 オペレーター(ふくimplicits、例えば、 Scalaz.IdentityTo(e1).⊹(e2)(Semigroup.NonEmptyListSemigroup(Semigroup.StringSemigroup)).

implicit def ValidationApply[X: Semigroup]: Apply[PartialApply1Of2[Validation, X]#Apply] = new Apply[PartialApply1Of2[Validation, X]#Apply] {
  def apply[A, B](f: Validation[X, A => B], a: Validation[X, A]) = (f, a) match {
    case (Success(f), Success(a)) => success(f(a))
    case (Success(_), Failure(e)) => failure(e)
    case (Failure(e), Success(_)) => failure(e)
    case (Failure(e1), Failure(e2)) => failure(e1 ⊹ e2)
  }
}

Monadまたは応用の方は、を選んだら良いでしょうか?

続いて発表します。(そうです。Ed)

いることを示サブ計算に基づく Option または [A] Validation[E, A] 組み合わせることができま Apply または Bind.するおそれがある場合は選んだのに。

ご利用の際は Apply, の構造計算が固定されます。すべての計算が実行され;その結果の一つできな影響を与えます。のみが"純粋"機能の概要をこういうことが起こった訳です。Monadic計算には、最初のサブ計算に影響を与え、後です。

場合に使用していましたMonadic検証構造を、初めての失敗が短期回路の検証としてありません Success 値をその後のバリデーションを実施します。しかし、私たちは幸せのためのサブ-検証する独立してもらえるので組み合わせを通じての応用は、収集に失敗しょう。の弱さの応用Functorsとなっています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top