我知道如何使用僅僅使用「綁定」操作的list monad來完成等效的Scheme(或Python)map
和filter
函數。可以「綁定」對List monad做一個減少嗎?
下面是一些斯卡拉說明:
scala> // map
scala> List(1,2,3,4,5,6).flatMap {x => List(x * x)}
res20: List[Int] = List(1, 4, 9, 16, 25, 36)
scala> // filter
scala> List(1,2,3,4,5,6).flatMap {x => if (x % 2 == 0) List() else List(x)}
res21: List[Int] = List(1, 3, 5)
,並在Haskell同樣的事情:
Prelude> -- map
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> [x * x])
[1,4,9,16,25,36]
Prelude> -- filter
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> if (mod x 2 == 0) then [] else [x])
[1,3,5]
計劃和Python也有一個reduce
功能往往與map
和filter
分組。 reduce
函數使用所提供的二元函數組合列表的前兩個元素,然後將其結合到下一個元素,然後繼續。計算值列表的總和或乘積的常用方法。下面是一些Python來說明:
>>> reduce(lambda x, y: x + y, [1,2,3,4,5,6])
21
>>> (((((1+2)+3)+4)+5)+6)
21
有沒有辦法做到這一點reduce
的使用上的列表單子只是綁定操作相當於?如果綁定本身無法做到這一點,那麼執行此操作的最「單點」方式是什麼?
如果可能,請在回答時限制/避免使用語法糖(即:在Haskell中使用do
表示法或在Scala中使用序列綜合法)。
我意識到綁定無法「突破」單子。我假設必須有一個不使用綁定的額外「解包」步驟。也就是說,直到解包步驟,'[1,2,3,4,5,6]'的結果和'+'的一些轉換將是'[21]'。有沒有什麼方法可以通過綁定加一個最終的「解包」操作來實現減少/摺疊? –
感謝您讓我知道它在Haskell和Scala中被稱爲「摺疊」。 –
@LaurenceGonsalves啊,我明白了。這仍然是不可能的。 'concatMap/>> ='一次只能查看一個元素,並且不能提供訪問以前結果的方法,所以沒有辦法像您一樣有一個累加器。 – sepp2k