7
私はscanl
を任意のADTに一般化する方法を考えてきました。プレリュードのアプローチは、すべてをリスト(すなわち、Foldable
)として扱い、構造の平坦なビューにscanl
を適用することです。代わりに、私はscanl
を、ツリーの各ノードからその子に状態を渡す操作として考える傾向がありますが、ルートから葉まで移動する際にはモノオプルのopを適用します。したがって、たとえば、Data.Tree
に、我々は持っている:だからこれは、任意のADTに対する `scan`sの意味のある一般化ですか?
scan :: (b -> a -> b) -> b -> Tree a -> Tree b
scan fn init (Node element children)
= Node (fn init element)
$ map (treeScan fn (fn init element)) children
、例えば:
main = do
prettyPrint $ scan (+) 0 $
Node 1 [
Node 1 [
Node 1 [],
Node 1 []],
Node 1 [
Node 1 [],
Node 1 []]]
結果内:各を通じてscanl
を適用すると同じです
1
|
+- 2
| |
| +- 3
| |
| `- 3
|
`- 2
|
+- 3
|
`- 3
元の構造を保持しながら独立してツリーのパスを作成します。
質問は簡単です:これは意味のある一般化ですか?つまり、それは一般的に使用されているのでしょうか?
['scanl1Of'](http://hackage.haskell.org/package/lens-4.13/docs/Control-Lens-Traversal.html#v:scanl1Of)があります。適切な 'Traversal'を使うと、このトリックを行うことができます。 – leftaroundabout
私は、この拡張された 'scanl'がすべての子に同じ' init'を渡すべきかどうかを確かめていません。 – chi
** chi **の 'scanl'は' scan :: Traversable f =>(b - > a - > b) - > b - > f a - > f bです。 scan f z a = evalState(トラバース(\ x - >変更(フリップf x)>>取得)a)z'。 – user3237465