Reduce 可以是不采用第一個元素的覆寫折疊。我想這個設計決定有一個答案,但我找不到。
uj5u.com熱心網友回復:
這兩種操作本質上是不同的。給它們取相同的名字會令人困惑。在Ruby中,等效的方法被呼叫Enumerable#inject(別名為Enumerable#reduce)并被多載以像 Scalascala.collection.Iterable.foldLeft[B](z: B)(op: (B, A) => B): B和scala.collection.Iterable.reduceLeft[B >: A](op: (B, A) => B): B. 你可以看到這引起的混亂紅寶石.
[注:從這里開始,我將使用 Scala 術語來指代兩種不同的操作,即fold和reduce。]
這兩種操作之間的一些區別是:
fold與空集合一起使用,reduce不是。在 Scala 中,它會拋出一個UnsupportedOperationException或者你可以使用scala.collection.Iterable.reduceLeftOption[B >: A](op: (B, A) => B): Option[B]. 在Haskell中,Scala 呼叫reduceLeft的Data.List.foldl1 :: Foldable t => (a -> a -> a) -> t a -> a原因是:因為您至少需要1 個元素。- 使用
reduce,結果型別與元素型別(或更準確地說,元素型別的超型別)相同,而使用fold,結果型別可以是任何。例如,您不能將字串集合的長度與 相加,reduce因為字串集合的結果型別reduce不能是數字,它必須是字串。 - 最重要的一個:
fold是一個通用的迭代操作,意思是,你可以用回圈或遞回做的所有事情,你都可以用fold. 如果你有fold,你不需要map,你不需要filter,你不需要forall,你不需要groupBy,你不需要scan,等等,當然你也不需要reduce。您可以使用fold. (我曾經為 Ruby 做過一次。)reduce不是通用的,你不能例如實作任何集合轉換(例如map,或者filter甚至只是reverse),因為結果型別為reduce是元素型別,不能是集合型別。
因為這兩個操作是如此不同,所以給它們起不同的名稱是有意義的:在 Scalafold和Haskell等中。在我最熟悉的語言 Ruby 中,它們具有相同的名稱,這導致困惑。reducefoldXfoldX1
uj5u.com熱心網友回復:
簡而言之,它們具有不同的型別約束,因此具有不同的型別簽名。a 的結果fold可以是任何你想要的。a 的結果reduce必須是元素的超型別。
這就是為什么fold并且reduce通常在動態型別語言中組合,但在靜態型別語言中分開。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/474435.html
