递归函数调用终止还是其实现错误?

时间:2017-06-09 19:09:34

标签: haskell

我正在通过 Haskell编程从第一原则开始工作,并且证明我已经正确回答了的问题1最后的事情而不是列表< / em>运动分段。以下函数调用不会终止,我无法判断是否预期或我的实现是否有问题。

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

认为每个a / x最终会递减/递增,直到它导致ifTrue分支并返回Nothing / Leaf

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

2 个答案:

答案 0 :(得分:3)

如果您尝试在func之外调用unfold,则可以理解程序永不终止的原因。在这里,我将func重命名为unfolder,因为Haskell linter不喜欢它与func参数同名。

靠近边界,unfolder返回以下值:

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

对于unfolder 0分支在下一次明确评估为Nothing,但分支为unfolder 1 ,评估为Just (0,1,2),等等无限期。

答案 1 :(得分:2)

您的实施会产生对unfold的无限次调用。

考虑第一个递归调用,其中您的初始种子值5被分为46左侧和右侧子树。在那里,您将这个新种子拆分为左侧的35以及右侧的57,因此您可以定义一个无限大的树。