アリスは無限にプラダから猫を取り出す | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/8179
これをF#版に直してみる。
実は、GetCatsメソッドを末尾呼び出しにして、F#のほうは無限に猫を取り出せる…という風にやろうと思ったのだが、この方式だと lst に詰め込むときにスタックオーバーフローになってしまう。
最初は head::tail 方式で書いていたのだが、なんか面倒になって(ツリー構造だから)、外部で list を持っているのが問題かも。
type IObject() = do ()
type Cat(name) =
inherit IObject()
member val Name:string = name with get, set
type Bag() =
inherit IObject()
member val Items:IObject list = [] with get, set
member x.Add(items) =
for it in items do
x.Items <- it :: x.Items
x
// 猫だけ取り出す
member x.GetCats() =
let rec cats (bag:Bag) =
let mutable lst = []
for it in bag.Items do
if it.GetType() = typeof<Cat> then
lst <- it :: lst
else
let bag = it :?> Bag
lst <- lst @ cats bag
lst
cats x
// main
// 入れ子のバッグ
let prada =
Bag().Add(
[Cat("mike");
Bag().Add(
[Cat("hop");
Cat("stop");
Cat("jump")]);
Cat("kuro");
Cat("shiro")] )
// 猫のみ取り出す
for it in prada.GetCats() do
let cat = it :?> Cat
printfn "cat: %s " cat.Name
// 無限バッグを作る
let mutable infbag = Bag().Add([Cat("Cheshire")])
infbag.Add([infbag]) |> ignore
// 無限に取り出す...ことはできない
for it in infbag.GetCats() do
let cat = it :?> Cat
printfn "cat: %s " cat.Name
