2017-06-09 4 views
3

私はのハスケルプログラミングから私が正しくの質問1に答えていることを証明していませんでした。最後に、エクササイズのサブセクション以外の何かがあります。次の関数呼び出しは終了せず、それが予期しているかどうか、実装に問題があるかどうかはわかりません。再帰関数呼び出しが終了するか、その実装に誤りがありますか?

data BinaryTree a = Leaf 
        | Node (BinaryTree a) a (BinaryTree a) 
        deriving (Eq, Ord, Show) 

unfold :: (a -> Maybe (a, b, a)) -> a -> BinaryTree b 
unfold func seed = 
    case (func seed) of 
    Just (l, m, r) -> Node (unfold func l) m (unfold func r) 
    Nothing -> Leaf 

私はそれがTrue枝を取り、Nothing/Leafを返すようにifの原因となるまで、各a/xは、最終的にインクリメント/デクリメントされることをを思うだろう。

func = (\x -> if (x < 0 || x > 10) 
       then Nothing 
       else Just (x - 1, x, x + 1)) 
unfold func 5 
-- Node (Node (Node (Node (Node (Node Leaf 0 ... ad infinitum 
+3

いい例。問題は、あなたが左の枝を取ることができ、次に右の枝を取ることができ、そして次に左と右を永遠に取ることができるということです。したがって、あなたは '5-1 + 1-1 + 1 .... 'それは無限に深い木を生成します。 – chi

答えて

2

この実装では、unfoldを無制限に呼び出します。

先頭のシード値5が、左と右のサブツリーについて46に分割されている最初の再帰呼び出しを考えてみます。ここでは、この新しいシードを左に35に分割し、右に57というように、無限大のツリーを定義します。

+0

この回答をお寄せいただきありがとうございます。私は今、1)この関数が期待どおりに動作していること、2)それが期待される動作であることが分かります。 – pdoherty926

3

funcunfoldの外に呼び出そうとすると、プログラムが終了しない理由がわかります。ここでは、funcunfolderに変更しました。なぜなら、Haskellリンターはfunc引数と同じ名前を持つのが好きではなかったからです。 枝明確周り次回Nothingに評価を残し、unfolder 0については

*So> unfolder 1 
Just (0,1,2) 
*So> unfolder 0 
Just (-1,0,1) 
*So> unfolder (-1) 
Nothing 

が、ブランチがあると評価され、unfolder 1です:境界に近く

は、 unfolderこれらの値を返します。 Just (0,1,2)など、無期限に。

+0

両方の回答を選択できたらいいのに、最初に提出されたので、mschmidtを選択しました。 – pdoherty926

関連する問題