我的任务是使用这个折叠功能,"获取一个列表并返回一棵树"。
data Tree a = Tip a | Node (Tree a) (Tree a)
unfoldTree :: (a -> Either n (a, a)) -> a -> Tree n
unfoldTree g h =
case g h of
Right (l, r) -> Node (unfoldTree g l) (unfoldTree g r)
Left c -> Tip c
a = [Int] n = Int
我相信我理解这里的概念,并且我尝试使用以下帮助方法来测试unfoldTree
createSimpleTree :: [a] -> Tree x
createSimpleTree xs = unfoldTree (\ys -> ys (firstHalf ys, secondHalf ys) ) xs
虽然这不起作用,但我认为这是由于中心线ys -> ys (firstHalf ys, secondHalf ys)
,因为我不确定如何使用Either
(我不知道它的官方名称抱歉还在学习!)
我已经尝试过在这里使用lambda但我不确定如果它是LEFT这样做,如果它是正确的吗?或者我可能完全走错了路。
问题:如何使用createSimpleTree [1,2,3,4]
生成带有值的树?
答案 0 :(得分:1)
在开始编写函数之前,这些类型需要解决一些问题。首先要注意的是,使用此展开,您无法编写类型为[a] -> Tree x
的函数:x
类型的值来自何处?但是,您可以尝试编写类型为[a] -> Tree a
的函数,方法是将值从输入列表移动到输出树中。
第二个问题是,使用此Tree a
类型无法表示空树:Tip
至少有一个a
,而Node
有{至少两个,因为两个分支中的每一个最终导致至少一个Tip
。因此,无法处理空输入列表的情况:createSimpleTree []
无法成功完成,无论您执行createSimpleTree
。
如果这是一项任务,unfoldTree
的类型和实施是在前面给我的,我会仔细检查我是否正确阅读了它们;如果是这样的话,我现在就放弃解决它,然后说“嘿,你给我的这些类型都不好,我现在应该做什么?”。这个投诉有几个可能的答案:首先,createSimpleTree
的签名肯定会被修复;第二,要么修改Tree类型(对unfoldTree
进行相应的更改),要么保证createSimpleTree
永远不会使用空列表调用。unfoldTree
那时你可以回过头来解决这个问题。
如果您自己这样做,我会说要自己修复树类型和data Tree a = Leaf | Node a (Tree a) (Tree a)
unfoldTree :: (a -> Maybe (n, a, a)) -> a -> Tree n
unfoldTree = undefined -- exercise for the reader
createSimpleTree :: [a] -> Tree a
createSimpleTree = unfoldTree f
where f = undefined -- exercise for the reader
的签名。例如,我将从
ERB.new('Name: <%= name %> <%= last %>')
答案 1 :(得分:1)
amalloy's answer在解释createSimpleTree
所需的类型以及传递空列表时出现的问题时非常有用。
如果您必须按原样求解createSimpleTree
而不关心创建部分函数(未为其所有输入定义的函数),请按照以下步骤进行操作:
createSimpleTree :: [a] -> Tree a
createSimpleTree xs = unfoldTree go xs
where
go :: [a] -> Either a ([a], [a])
go [] = error "Empty list in createSimpleTree"
go [x] = Left x
go xs =
let n = length xs `div` 2
in Right (take n xs, drop n xs)