SwiftでfilterM

すごいH本最大の難所と僕が勝手に思っているfilterM
Swiftで同じ事出来ないかなと模索してみたところ、できちゃったので、ここに記録。

func filterM<T>(_ p: (T)->[Bool],_ array: [T]) -> [[T]] {
    return array.first.map { x in
        let xs = Array( array.suffix(from: 1) )
        let result: [[T]] = p(x).flatMap{ flg -> [[T]] in
            [filterM(p,xs)].flatMap{ ys -> [[T]] in
                flg ? [[x] + (ys.first ?? []) ] : ys }
        }
        return result
    } ?? []
}

print(filterM( { _ in [true,false] }, [1,2,3] ))

// [[1, 2, 3], [2, 3], [3]]