Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
repmin如何在Haskell中的树中放置值?_Haskell_Tree_Fixpoint Combinators_Tying The Knot - Fatal编程技术网

repmin如何在Haskell中的树中放置值?

repmin如何在Haskell中的树中放置值?,haskell,tree,fixpoint-combinators,tying-the-knot,Haskell,Tree,Fixpoint Combinators,Tying The Knot,我非常喜欢repmin问题: 写下repmin::Tree Int->Tree Int,在一次传递中用最小值替换树中的所有数字 如果我在python中编写类似的东西,我会使用它们的引用来传递值(假设一个元素列表而不是数字就足够了): def repmin(树,wrapped_min_link=None): x、 子休息=树 如果“包装的\u最小\u链接”为“无”: 包装的\u最小\u链接=[x] 其他: [m] =已包装的\u最小\u链接 包裹的最小链接=[min(m,x)] n=len(子休息

我非常喜欢
repmin
问题:

写下
repmin::Tree Int->Tree Int
,在一次传递中用最小值替换树中的所有数字

如果我在python中编写类似的东西,我会使用它们的引用来传递值(假设一个元素列表而不是数字就足够了):

def repmin(树,wrapped_min_link=None):
x、 子休息=树
如果“包装的\u最小\u链接”为“无”:
包装的\u最小\u链接=[x]
其他:
[m] =已包装的\u最小\u链接
包裹的最小链接=[min(m,x)]
n=len(子休息)
子REST_min=[None]*n
对于范围(n)中的i:
如果子休息[i]:
子REST\u min[i]=repmin(子REST[i],包装的\u min\u链接)
返回(已包装的\u min\u链接,子休息\u min)
在我看来,这似乎是一种合适的方法,可以让人在Haskell的打结解决方案中保持清醒(我写这篇文章是为了:

copyRose::Tree Int->Int->(Tree Int,Int)
copyRose(节点x[])m=(节点m[],x)
copyRose(节点x fo)m=
让
unzipIdMinimum=
foldr(\~(a,b)~(as,bmin)->(a:as,b`min`bmin))([],maxBound::Int)
(fo',y)=最小值。地图(翻页复制m)$fo
in(节点m fo',x`min`y)
repmin::Tree Int->Tree Int
repmin=(loop.uncurry)copyRose
然而,我认为解决方案的效果非常不同。以下是我对后者的理解:

让我们重写一下:

我认为它的工作原理与
snd
的工作原理类似,snd的惰性程度与
let
中的模式匹配相同

因此,当
repmin
遍历树时,它是:

  • 在树中建立最小值,作为对的第二个元素返回
  • 在每个节点中留下
    snd$copyRose(树,m)
因此,当遍历结束时,程序知道
snd$copyRose(tree,m)
(即树中的最小值)的值,并且能够在计算树的某个节点时显示该值


我是否正确理解Haskell中的
repmin

这与其说是一个答案,不如说是一个扩展注释,但我并不认为您的实现是一个简单的过程。它看起来像是遍历了一次树,生成了一个新的、延迟生成的树和全局最小值,但实际上它生成了一个延迟生成的树和一个巨大的thunks树,最终将计算最小值。为了避免这种情况,您可以通过急切地生成树来更接近Python代码,同时跟踪最小值

您会注意到,我已经将类型从
Int
概括为任意
Ord
类型。您还将注意到,我使用了不同的类型变量来引用给定树中元素的类型,以及传入的最小值的类型来生成一个新树。这让类型系统告诉我是否混淆了它们

repmin::树a->树a
repmin=(loop.uncurry)copyRose
copyRose::Ord a=>树a->b->(树b,a)
copyRose(节点x ts)最终最小值

|(ts',m)我不知道,但我真的不喜欢你的
unzipidmimum
函数,因为它不计算
min
。我认为可能有更好的方法。@dfeuer会添加类似于
let bmin'=min b bmin in in(join seq)bmin'
的内容使事情变得更好吗?不,你需要重塑事物。@dfeuer“重塑”是什么意思?我们是否需要整体地重塑
unzipidmimum
copyTree
?@dfeuer也许
unzipidmimum=foldr(\(a,b)(as,!bmin)->(a:as,b`min`bmin))([],maxBound::Int);(fo',!y)=最小值
将按原样计算最小值(从右到左,自下而上)。它仍然会以元组的形式一次展开整个树结构的副本,最有可能的是,首先,然后在请求结果树时从顶部重新遍历它,自顶向下重建节点。(续)谢谢你的回答。我试图将我的解决方案与中的解决方案相匹配(pdf-9.1“the
repmin
问题”第122页,第130页)。它有同样的问题吗?@ZhiltsoffIgor,是的,有。我刚刚意识到用我的方法计算最小值是没有必要的;实际上,你可以做一些事情,比如你的方法,让每件事都变得严格。但我的方式更优雅地处理空列表挑战。此外,“thunks之树”是什么意思?从我的角度来看,每个节点中的递归调用从其所有子节点收集thunk并继续进行。我在上面写的
(join-seq)(min-b-bmin)
会严格执行它吗?我想我们不需要
let
,因为
join f
的参数正在被共享。@zhiltsofigor
seq x y
的意思是,“当
y
被强制时,也强制
x
”。因此,
seq x
什么也没说。这就是我对它的理解。
loop f b = let cd = f (b, snd cd) in fst cd