SYB の gfoldl を使用して、listify の結果を一度にマップできますか?
たとえば、次のコードを考えてみましょう。
extractNums :: Expr -> [Int]
extractNums e = map numVal $ listify isNum e
where isNum :: Expr -> Bool
isNum (Num _) = True
isNum _ = False
numVal :: Expr -> Int
numVal (Num i) = i
numVal _ = error "Somehow filter did not work?"
numVal 関数では、Num コンストラクターだけに関心があるのに、Expr 型のさまざまなデータ コンストラクターを考慮しなければならないのが好きではありません。isNum と numVals を以下の vals 関数のようなものに置き換えます。
vals :: [Int] -> Expr -> [Int]
vals xs (Num x) = x : xs
vals xs _ = xs
これは gfoldl で実行できますか? どのように?