ツリーのタイプを定義しました。
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Read , Eq, Ord, Show)
さて、テキスト ファイルにはバイナリ ツリーがあります。次に例を示します。
(7 (3 (1 () ()) (5 () ())) (11 (9 () ()) (13 () ())))
このツリーの表現を読み取り、Tree 型のツリーを構築する関数を作成するにはどうすればよいでしょうか?
ツリーのタイプを定義しました。
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Read , Eq, Ord, Show)
さて、テキスト ファイルにはバイナリ ツリーがあります。次に例を示します。
(7 (3 (1 () ()) (5 () ())) (11 (9 () ()) (13 () ())))
このツリーの表現を読み取り、Tree 型のツリーを構築する関数を作成するにはどうすればよいでしょうか?
ヒントを教えてください:
ツリーは自己相似構造です。それはあなたが使うべきだと思います...
()
木を表すEmpty
ツリーの表現にはこの構造があり(string_data_with_type_a string_tree string_another_tree)
ます。これら 2 つの括弧は省略でき、スペースでこれら 3 つのパラメーターを区切ることができるようです。
それで全部です。よい旅を、ハスケラー。
聞けば答えられる。
あなたは解析関数を書いています。基本的なタイプは のようなものですがString -> Tree Int
、考慮に値する強力な改良点がいくつかあります。
まず、すべてString
の s が実際に s に変換できるわけではないTree
(つまり、ツリーではない) ため、関数をの")"
ような型に絞り込む方がよい。モナドは失敗の可能性を示している。String -> Maybe (Tree Int)
Maybe
Int
第二に、おそらくパーサーを再発明したくないでしょう。Read
typeclass を使用して、パーサーのコレクションにアクセスできます。だからあなたはかもしれません
Read a => String -> Maybe (Tree a)
Safe
てアクセスしますreadMay :: Read a => String -> Maybe a
Tree
次に、解析コンポーネントをビルドします。第三に、Tree
s は非常に再帰的であり、括弧内の Lispy 文法は非常に再帰的であり、パーサーも再帰的であるべきです。この目的のために、単一のノード"(...)"
を解析し、必要に応じて内部ノードを再帰的に解析することに集中してください。
最後に、最終的にはさらに強力な解析ツールを検討することをお勧めします。Parsec
クラスよりもはるかに強力で、Read
小さくて単純な部分からより複雑で再帰的なパーサーを簡単に構築できます。