我正在通过 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
最终会递减/递增,直到它导致if
取True
分支并返回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
答案 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
被分为4
和6
左侧和右侧子树。在那里,您将这个新种子拆分为左侧的3
和5
以及右侧的5
和7
,因此您可以定义一个无限大的树。