函数像catMaybes,但计算Nothing值

Uli*_*ler 11 haskell list maybe

我有一个这样的列表:

let foo = [Just 1, Just 2, Nothing, Just 3, Nothing, Nothing]
Run Code Online (Sandbox Code Playgroud)

通过使用catMaybes我只能提取Just构造的值:

catMaybes foo -- [1,2,3]
Run Code Online (Sandbox Code Playgroud)

我现在正在寻找一个函数,它不仅可以生成一个Justs 列表,还可以Nothing通过遍历它来获得有限列表的s 计数.它应该有这样的签名:

catMaybesCount :: [Maybe a] -> ([a], Int)
Run Code Online (Sandbox Code Playgroud)

注意:此问题已回答Q&A风格,因此故意不会显示任何研究工作!

Dan*_*ner 23

import Data.Monoid
import Data.Foldable

catMaybesCount = foldMap inject where
    inject Nothing  = ([ ], Sum 1)
    inject (Just x) = ([x], Sum 0)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案值得扩大.关键的想法是:(a)`catMaybes`和`count`都是折叠,(b)[折叠是由幺半群组成](http://byorgey.wordpress.com/2012/11/05/foldr-is- (3)幺半群的产物是幺半群(实例(Monoid a,Monoid b)=> Monoid(a,b)`. (2认同)

Wil*_*ess 5

我们可以有一个左折叠用于严格计数和一个右折叠同时进行惰性列表构建:

catMC :: (Num t) => [Maybe a] -> ([a], t)
catMC xs = g 0 xs 
  where 
    g !c (Nothing:xs) = g (c+1) xs 
    g !c (Just  v:xs) = let (a,b)=g c xs in (v:a,b) 
    g !c []           = ([],c)
Run Code Online (Sandbox Code Playgroud)

这也适用于无限列表,只要我们不访问结果的count字段(snd),同时以严格,有效的方式计算计数,就像可变累加器变量一样.