2010-05-20 99 views
2

我想弄清楚从here工作(我明白flatten,插入和foldr)如何确切treeort。问题了解在Haskell tr​​eesort

我想在treesort中正在做的是对列表上的每个元素应用插入,从而生成一棵树并将其展平。我在这里无法克服的唯一问题是列表(即函数的参数)隐藏的地方(因为除了函数类型声明外,它没有被写入任何地方作为参数)。

还有一件事:由于点运算符是函数组合,为什么当我更改时出错:treesort = flatten . foldr insert Leaftreesort = flatten(foldr insert Leaf)

回答

8

什么在treesort正在做正在为列表中的每个元素应用插入,从而生成一棵树,然后展开它。

没错。

[哪里列表隐藏?]

在函数式语言,你不必给函数类型的值的参数。例如,如果我写

f = concat . map (map toUpper) 

我得到类型为[[Char]] -> [Char]的函数。即使在定义方程中没有参数,这个函数也会期待一个参数。 这是正是,如果我写了

f strings = (concat . map (map toUpper)) strings 

由于点运算符是函数组合一样,为什么错了改变f . gf (g)

它们并不意味着同样的事情。当每个应用于x时会发生什么?

(f . g) x = f (g x) 

(f (g)) x = (f g) x 

你可以看到不同的应用程序相关联,并f. gf g不同。

这是一个类型错误,因为foldr insert Leaf是从列表到树的函数,并且flatten意味着应用于单个树而不是函数。

+0

我不确定'f strings = ...和'f = \ strings - > ...'是同一件事情。 – ony 2010-05-20 05:34:59

+1

@ony:和['a“,”b“]”和“a”一样:“b”:[]';他们是编写相同价值的两种不同方式。 – 2010-05-20 05:53:18

6

先回答你的最后一个问题,因为.是一个函数合成运算,它有两个功能(在这种情况下flattenfoldr insert Leaf)你得到一个错误。如果你想重写代码,而无需使用.,你需要创建一个函数,它的一些参数:

-- // Pass the 'list' to the first function and the 
-- // result of the call to the second function 
treesort list = flatten (foldr insert Leaf list) 

这也解释了其中list参数躲藏。在编写功能,您无需明确写入参数,因为表达式f . g的结果是一个函数,需要一些参数,调用g然后调用f

-- // function composition.. 
composed = f . g 
-- // ..is equivalent to declaring a function: 
composed x = f (g x) 
+0

严格地说,在链路的treesort函数接受一个列表参数,而不是一棵树,所以“树”可能不是变量名的最佳选择。 – 2010-05-20 02:03:26

+0

@彼得:是的,我也意识到这一点 - 感谢修正。 – 2010-05-20 02:10:09

1

有时候,只要你不熟悉无意义的风格,在心理上进行epsilon转换是有用的。

如果f是与功能类型的表达式,那么就可以将其转换为 。\ E - >(F)在线

而且,如果我们有像

a = \e -> (f) e 

我们总能定义安全地把它改写为

a e = (f) e 

因此

treesort = flatten . foldr insert Leaf 

相同

treesort list = (flatten . foldr insert Leaf) list