如何使用此展开功能?

时间:2017-04-03 21:02:37

标签: haskell

我的任务是使用这个折叠功能,"获取一个列表并返回一棵树"。

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]生成带有值的树?

2 个答案:

答案 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)