問題タブ [either]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scala - Try[Result]、IO[Result]、Eir[Error,Result]、最終的にどちらを使うべきか
さまざまな種類の失敗をエレガントに処理するために、メソッドのシグネチャを知りたいです。
この質問は、Scala でのエラー処理に関して私がすでに持っていた多くの質問の要約です。ここでいくつかの質問を見つけることができます:
今のところ、次のことを理解しています。
- どちらも、失敗する可能性のあるメソッド呼び出しの結果ラッパーとして使用できます
- Try は右にバイアスされたどちらかであり、失敗は致命的ではない例外です
- IO (scalaz) は、IO 操作を処理する純粋なメソッドを構築するのに役立ちます
- 3つすべてが理解のために簡単に使用できます
- flatMap メソッドに互換性がないため、理解のために 3 つすべてを簡単に混在させることはできません。
- 関数型言語では、通常、致命的でない限り例外をスローしません。
- 本当に例外的な条件に対しては、例外をスローする必要があります。これがTryのアプローチだと思います
- Throwable の作成には JVM のパフォーマンス コストがかかり、ビジネス フロー制御に使用することは意図されていません。
リポジトリ層
今、私が持っていると考えてくださいUserRepository
。はUserRepository
ユーザーを格納し、メソッドを定義しますfindById
。次の障害が発生する可能性があります。
- 致命的な失敗 (
OutOfMemoryError
) - データベースにアクセスできない/読み取れないための IO 障害
さらに、ユーザーが見つからない可能性があり、Option[User]
結果につながります
リポジトリの JDBC 実装、SQL を使用すると、致命的ではない例外 (制約違反など) をスローできるため、Try を使用することは理にかなっています。
IO 操作を扱っているので、純粋な関数が必要な場合は IO モナドも意味があります。
したがって、結果のタイプは次のようになります。
Try[Option[User]]
IO[Option[User]]
- 他の何か?
サービス層
ここで、以前に定義されたリポジトリを使用するUserService
メソッドを提供するビジネス層 を紹介しましょう。updateUserName(id,newUserName)
findById
次の障害が発生する可能性があります。
- サービス層に伝搬されたすべてのリポジトリ障害
- ビジネス エラー: 存在しないユーザーのユーザー名は更新できません
- ビジネス エラー: 新しいユーザー名が短すぎます
結果のタイプは次のようになります。
Try[Either[BusinessError,User]]
IO[Either[BusinessError,User]]
- 他の何か?
ここでの BusinessError は例外的なエラーではないため、Throwable ではありません。
for 内包表記の使用
メソッド呼び出しを結合するために for-comprehension を使い続けたいと思います。
for-comprehension で異なるモナドを簡単に混在させることはできないので、すべての操作に対してある種の統一された戻り値の型を使用する必要があると思いますよね?
現実世界の Scala アプリケーションで、さまざまな種類の障害が発生する可能性があるときに、どうやって for 内包表記を使い続けることができるのだろうか。
今のところ、for-comprehension は私にとっては問題なく機能します。すべて返されるサービスとリポジトリを使用していますEither[Error,Result]
が、さまざまな種類の障害がすべて溶け合っており、これらの障害を処理するのは一種のハッキーになります。
for-comprehension を使用できるように、異なる種類のモナド間の暗黙的な変換を定義していますか?
失敗を処理する独自のモナドを定義しますか?
ちなみに、近いうちに非同期 IO ドライバーを使用する予定です。したがって、戻り値の型はさらに複雑になる可能性があると思います。IO[Future[Either[BusinessError,User]]]
私のアプリケーションは空想的ではありませんが、何を使用すればよいか本当にわからないため、アドバイスを歓迎します。これは、クライアント側に表示できるビジネス エラーを区別できる API にすぎません。技術的なエラー。私はエレガントで純粋な解決策を見つけようとします。
haskell - モナドシーケンスでモナド型を変更することは可能ですか?
ラップされたタイプを変更できることを知っているので、
しかし、変更することは可能m
ですか? m
とが と の両方MonadError
で実装されている場合、どういうわけかそれらをチェーンできますか? 明らかに、それらを直接チェーンすることはできません。ただ、どちらの場合でも電話してしまう状況にあるのですが、それ以上の解決策が見つかりません。Either ErrorA
Either ErrorB
Left
show
明示的にチェックしなくても、最初のエラーで停止するというモナドの動作を適切に使用できません。
scala - Scala.Either getOrElse メソッド
これを入力すると、すべて正常に動作するのはなぜですか?
しかし、このコンパイルを入力すると失敗しますか?
コンパイル エラー:
値 getOrElse は java.io.Serializable
println(RightString, Int.left getOrElse RightString, Int.left getOrElse LeftString, Int)のメンバーではありません
getOrElse
だから私はメソッド呼び出し を連鎖することはできません
scala - Scala でのチェーン検証
case class
コマンドライン構成情報を含むScalaがあります。
各値が次のようになっていることを確認する検証関数を作成していますSome
。
しかし、Haskell のモナドを理解していれば、検証を連鎖させることができるはずです (疑似構文):
いずれかのconfig.XXX
式が を返す場合Failure
、( ) 全体validateConfig
が失敗し、それ以外の場合Success(config)
は返されます。
Try
、または他のクラスでこれを行う方法はありますか?
scala - Futures (Twitter) と Each を Scala で組み合わせる
Twitter の先物を (Finagle スタックの一部として) 使用していますが、(ビジネス) 例外を使用してアプリケーションのフローを制御するという概念は好きではありません。例外はメソッド シグネチャに表示されないからです。
そこで、代わりに Future[Either[A,B]] を使用するというアイデアがありました。
しかし、私はこの概念で先物を理解するために使用する際にいくつかの問題があります:
たとえば、次のようなリポジトリ メソッドがあります。
そして、このレポを使用し、他のチェックを行い、トークンも作成するハンドラーメソッド
getUserCredentialsByNickname(..) の後の for 内包表記の呼び出しは、この呼び出しが Right[UserCredentials] を返す場合にのみ実行する必要がありますが、返されたそれぞれからの詳細なエラー情報もハンドラーから返す必要があります。
scala - if ガードを理解するため
if ガードの理解にはどのように使用すればよいですか?
使用中にこのエラーが発生しました。
編集: 別のエラーが発生しました。ガードを使用するとオプションの結果が返ってくると思います。
EDIT2
scala - ガードがエラーをスローする場合の理解のために
このように if ガードを内包するために使用すると、1 つのエラーが発生します。
コード:
エラー: