Scala、折りたたみ脚本と怠zyな評価をサポートするマップの間のクロス

StackOverflow https://stackoverflow.com/questions/19841403

質問

新しいコレクションにマッピングしたいコレクションがありますが、結果の各値は何らかの形で値に依存します。

val result:List[B] = (myList:List[A]).foldLeft(C -> List.empty[B]){ 
  case ((c, list), a) =>
    ..some function returning something like..
    C -> (B :: list)
} 

ここでの問題は、結果のリストを取得するためにリスト全体を反復する必要があることです。私は、[a]をトラバーサブルに移動する[b]をmapsapableonce [b]にマップし、メンバーのみを呼び出すようにしたいと思ったとしますか?かなり慣習的な問題であるように思えるので、これに共通のアプローチがあるかどうか疑問に思います。私が現在持っているのは:

implicit class TraversableOnceEx[T](val self : TraversableOnce[T]) extends AnyVal {

   def foldyMappyFunction[A, U](a:A)(func:(A,T) => (A,U)):TraversableOnce[U] = {
     var currentA = a
     self.map { t =>
        val result = func(currentA, t)
        currentA = result._1
        result._2
     }
   } 
}

機能的な純度に関する限り、並行して実行することはできませんでしたが、そうでなければ健全に思えます。

例は次のとおりです。各要素を返してください。その要素が以前に登場したのが初めてである場合。

val elements:TraversableOnce[E]
val result = elements.mappyFoldyFunction(Set.empty[E]) {
 (s, e) => (s + e) -> (e -> s.contains(e))
}
result:TraversableOnce[(E,Boolean)]
役に立ちましたか?

解決

州のモナドを利用できるかもしれません。これがScalazを使用して書き直した例です。

import scalaz._, Scalaz._

def foldyMappy(i: Int) = State[Set[Int], (Int, Boolean)](s => (s + i, (i, s contains(i))))

val r = List(1, 2, 3, 3, 6).traverseS(foldyMappy)(Set.empty[Int])._2

//List((1,false), (2,false), (3,false), (3,true), (6,false))
println(r)

他のヒント

あなたが必要とするように見えます seqview. 。使用する view また view(from: Int, until: Int) リストの非厳格なビューを作成する方法。

あなたのcontainsチェックは常に結果として生じるので、私はあなたの例を本当に理解していません false.

foldLeft 異なります。リストのすべての要素を集約することにより、単一の値になります。あなたは明らかに必要です map (List => List).

とにかく、怠lazについてのあなたの質問に答える:あなたは使うべきです Stream それ以外の List. Stream 実際に呼び出す前に尾を評価しません。

APIをストリーミングします

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