理解 Haskell 中的树排序问题

发布于 2024-09-02 04:42:29 字数 378 浏览 1 评论 0原文

我试图弄清楚 这里 的树排序究竟是如何工作的(我理解展平、插入和文件夹)。

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

还有一件事:既然点运算符是函数组合,为什么当我更改时会出现错误: treesort = flatten 。 foldr insert Leaftreesort = flatten(foldr insert Leaf )

I am trying to figure out how exactly does treesort from here work (I understand flatten, insert and foldr).

I suppose what's being done in treesort is applying insert for each element on the list thus generating a tree and then flattening it. The only problem I can't overcome here is where the list (that is the argument of the function) is hiding (because it is not written anywhere as an argument except for the function type declaration).

One more thing: since dot operator is function composition, why is it an error when I change: treesort = flatten . foldr insert Leaf to treesort = flatten( foldr insert Leaf )?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

网白 2024-09-09 04:42:29

树排序中所做的是对列表中的每个元素应用插入,从而生成一棵树,然后将其展平。

完全正确。

[列表隐藏在哪里?]

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

f = concat . map (map toUpper) 

我会得到一个 [[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 旨在应用于单个树,而不是函数。

what's being done in treesort is applying insert for each element on the list thus generating a tree and then flattening it.

Exactly right.

[Where is the list hiding?]

In a functional language, you don't have to give the arguments of a value of function type. For example if I write

f = concat . map (map toUpper) 

I get a function of type [[Char]] -> [Char]. This
function expects an argument even though there's no argument in the defining equation.
It's exactly the same as if I had written

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

Since the dot operator is function composition, why is it wrong to change f . g to f (g)?

They don't mean the same thing. What happens when each is applied to x?

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

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

You can see the applications associate differently, and f. g is different from f g.

It's a type error because foldr insert Leaf is a function from lists to trees, and flatten is meant to be applied to a single tree, not to a function.

温柔嚣张 2024-09-09 04:42:29

首先要回答你的最后一个问题,你会收到一个错误,因为 . 是一个函数组合运算符,它需要两个函数(在本例中 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)

To answer your last question first, you're getting an error because . is a function composition operator that takes two functions (in this case flatten and foldr insert Leaf). If you want to rewrite the code without the use of ., you'll need to create a function that takes some parameter:

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

This also explains where the list parameter was hiding. When composing functions, you don't need to write parameters explicitly, because the result of the expression f . g is a function that takes some parameter, calls g and then calls f:

-- // function composition..
composed = f . g
-- // ..is equivalent to declaring a function:
composed x = f (g x)
云巢 2024-09-09 04:42:29

有时,只要您不熟悉无意义的风格,在心里进行 epsilon 转换就会很有用。

如果 f 是函数类型的表达式,则可以将其转换为
\e-> (f) e

并且,如果我们有一个像这样的定义,

a = \e -> (f) e

我们总是可以安全地将其重写为

a e = (f) e

因此

treesort = flatten . foldr insert Leaf 

treesort list = (flatten . foldr insert Leaf) list

Sometimes, as long as you are not familiar with the pointless style, it is useful to do epsilon-conversion mentally.

If f is an expression with function type, then one can convert it to
\e -> (f) e

And, if we have a definition like

a = \e -> (f) e

we can always safely rewrite it as

a e = (f) e

Thus

treesort = flatten . foldr insert Leaf 

is the same as

treesort list = (flatten . foldr insert Leaf) list
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文