6

私は現在少し疲れているので、明らかなことを見逃しているかもしれません。

var _minVal: Option[Double]s のコレクションに含まれる最小値を保持する があります(Doubleコレクションが空の場合は None)

コレクションに新しいアイテムを追加するとき_minValは、が None であるか、新しいアイテムよりも大きい (= 新しい最小値の候補) かどうかも確認する必要があります。

から行きました

_minVal = Some(_minVal match {
    case Some(oldMin) => if (candidate < oldMin) candidate
                         else                    oldMin
    case None         =>                         candidate
})

(あまりドライではない)

_minVal = Some(min(_minVal getOrElse candidate, candidate))

しかし、まだ何かが足りないと思います…</p>

4

2 に答える 2

10

Scalaz がなければ、いくらかの RY を支払うことになります。しかし、私はそれを次のように書きます:

_minVal = _minVal map (candidate min) orElse Some(candidate)

編集

Specs / Specs2で有名なEric Torreborreは親切にも、私が見逃していたScalazソリューションを追求してくれました。テストフレームワークの専門家である彼は、命令的で副作用のあるオリジナルではなく、テスト形式で回答を書きました。:-)

これは、副作用の代わりに を使用したバージョンと、エリックが大変な作業を行った今、私のひねりを_minVal加えDoubleたものです。Int

// From the question (candidate provided for testing purposes)
var _minVal: Option[Double] = None
def candidate = scala.util.Random.nextDouble

// A function "min"
def min = (_: Double) min (_: Double)

// A function "orElse"
def orElse = (_: Option[Double]) orElse (_: Option[Double])

// Extract function to decrease noise
def updateMin = _minVal map min.curried(_: Double)

// This is the Scalaz vesion for the above -- type inference is not kind to it
// def updateMin = (_minVal map min.curried).sequence[({type lambda[a] = (Double => a)})#lambda, Double]

// Say the magic words
import scalaz._
import Scalaz._   

def orElseSome = (Option(_: Double)) andThen orElse.flip.curried
def updateMinOrSome = updateMin <*> orElseSome

// TAH-DAH!
 _minVal = updateMinOrSome(candidate)
于 2011-08-12T21:11:23.547 に答える
7

Scalazを使用したDanielの回答の更新は次のとおりです。

カリー化された「min」関数は次のとおりです。

def min = (i: Int) => (j: Int) => if (i < j) i else j 

そして2つの変数:

// the last minimum value
def lastMin: Option[Int] = None

// the new value
def current = 1

では、2 つの新しい関数を定義しましょう

// this one does the minimum update
def updateMin = (i: Int) => lastMin map (min(i))

// this one provides a default value if the option o2 is not defined
def orElse = (o1: Int) => (o2: Option[Int]) => o2 orElse Some(o1)

次に、 @dibblego によるFunction1[T, _] が applicative functorである理由の優れた説明を使用して、「現在の」変数の繰り返しを回避できます。

(updateMin <*> orElse).apply(current) === Some(current)
于 2011-08-22T01:07:53.280 に答える