にすべてのフィルタ機能を適用します。私はそれらを既存のbuilder
の値に適用したいので、None
の場合は、そのまま返します。は、私はこのように見える機能を有する値
上記のコードは私が思いつくことができる最高ですが、どういうわけかMonoidでこれを行うことができると感じています - Noneの場合はidentity
を返してください。
残念ながら、わかりやすいものを定義する方法を理解できません。または、これを行う方法がより良い/異なる場合は、
私は猫を使用しています。何か案は?
にすべてのフィルタ機能を適用します。私はそれらを既存のbuilder
の値に適用したいので、None
の場合は、そのまま返します。は、私はこのように見える機能を有する値
上記のコードは私が思いつくことができる最高ですが、どういうわけかMonoidでこれを行うことができると感じています - Noneの場合はidentity
を返してください。
残念ながら、わかりやすいものを定義する方法を理解できません。または、これを行う方法がより良い/異なる場合は、
私は猫を使用しています。何か案は?
私はあなたの場合にはA => M[A]
の構造が少し不必要だと思います。この例で使用するフィルタ関数は、実際にはOption[Builder => Builder]
に相当します。結果がSome
またはNone
のいずれであるかを判断するのに、Builder
引数を使用しないためです。さらに、機能をBuilder => Builder
に簡略化すると、.getOrElse(identity)
となります。
このアイデアを使用する実装は2つあります。彼らは本当に猫に頼っていません。
def createBuilder(
builder: InitialBuilder, name: Option[String], useCache: Boolean, timeout: Option[Long]
): Builder = {
def builderStage[T](param: Option[T])(modify: T => Builder => Builder): Builder => Builder =
param.fold(identity[Builder](_))(modify)
val stages: List[Builder => Builder] = List(
builderStage(name)(n => _ withName n),
// `Boolean` is equivalent to `Option[Unit]`, and we convert it to that representation
// Haskell has a special function to do such a conversion `guard`.
// In Scalaz you can use an extension method `useCache.option(())`.
// In cats a similar `option` is provided in Mouse library.
// But you can just write this manually or define your own extension
builderStage(if (useCache)().some else none)(_ => _.withCache),
builderStage(timeout)(t => _ withTimeout t)
)
// It should be possible to use `foldK` method in cats, to do a similar thing.
// The problems are that it may be more esoteric and harder to understand,
// it seems you have to provide type arguments even with -Ypartial-unification,
// it folds starting from the last function, because it's based on `compose`.
// Anyway, `reduceLeft(_ andThen _)` works fine for a list of plain functions.
stages.reduceLeft(_ andThen _)(builder)
}
もう一つの可能性はflatten
に単にidentity
にそれらを強制することなく、None
秒を削除しList
Option
のS、次のとおりです。
def createBuilder2(
builder: InitialBuilder, name: Option[String], useCache: Boolean, timeout: Option[Long]
): Builder = {
val stages: List[Option[Builder => Builder]] = List(
name.map(n => _ withName n),
if (useCache) Some(_.withCache) else None,
timeout.map(t => _ withTimeout t)
)
stages.flatten.reduceLeft(_ andThen _)(builder)
}
驚くべき!ありがとう、確かに探検する価値のある素晴らしいアイデア! –
*なしの場合の身元を返す*アイデンティティを返します(。ゼロ)?意味は、 'Monoid [文字列] .zero'を空の文字列にするといいでしょうか? –
@YuvalItzchakov hmm、最初の 'builder'を返すために' identity'関数を適用することを意味すると確信しています... –
ああ、あなたは 'Monoid [Builder]'について話していますか? –