如何解决repmin如何在Haskell的树中放置值?
我真的很喜欢db=psycopg2.connect(host="localhost",user="anton",password="password",dbname="mytest",options='-c standard_conforming_strings=off')
问题:
写下
repmin
,它一次将树中的所有数字替换为最小值。
如果我在python中编写类似的代码,我将通过它们的引用传递值(假设用一个元素列表代替数字就足够了):
repmin :: Tree Int -> Tree Int
在我看来,这是一种在Haskell中打结解决方案的合适方法(我为rose trees from Data.Tree
编写了这种方法):
def repmin(tree,wrapped_min_link=None):
x,subforest = tree
if wrapped_min_link is None:
wrapped_min_link = [x]
else:
[m] = wrapped_min_link
wrapped_min_link = [min(m,x)]
n = len(subforest)
subforest_min = [None] * n
for i in range(n):
if subforest[i]:
subforest_min[i] = repmin(subforest[i],wrapped_min_link)
return (wrapped_min_link,subforest_min)
但是,我认为解决方案的工作方式大不相同。这是我对后一种的理解:
让我们稍微重写loop
for (->)
:
copyRose :: Tree Int -> Int -> (Tree Int,Int)
copyRose (Node x []) m = (Node m [],x)
copyRose (Node x fo) m =
let
unzipIdMinimum =
foldr (\ ~(a,b) ~(as,bmin) -> (a:as,b `min` bmin)) ([],maxBound :: Int)
(fo',y) = unzipIdMinimum . map (flip copyRose m) $ fo
in (Node m fo',x `min` y)
repmin :: Tree Int -> Tree Int
repmin = (loop . uncurry) copyRose
我认为这是loop
for (->)
的工作方式,因为loop f b = let cd = f (b,snd cd) in fst cd
的懒惰程度与snd
中的模式匹配一样。
因此,当let
穿过树时,它是:
- 在树中建立最小值以作为对的第二个元素返回。
- 在每个节点中留下
repmin
。
因此,遍历结束时,程序会知道snd $ copyRose (tree,m)
的值(即树中的最小值),并能够在某些节点上显示正在计算树的数量。
我对Haskell的snd $ copyRose (tree,m)
理解正确吗?
解决方法
这不是一个扩展的评论,而是一个答案,但是我并不认为您的实现是单次通过。它看起来像遍历树一次,看起来像是遍历了树,产生了一个新的,由懒惰生成的树和全局最小值,但实际上,它 产生了一个由懒惰生成的树和一棵巨大的树。最终将计算出最小值的重击为了避免这种情况,您可以通过急切生成树并随时随地跟踪最小值来接近Python代码。
您会注意到,我已将类型从Int
推广到任意Ord
类型。您还将注意到,我习惯于使用不同的类型变量来指代给定树中的元素类型以及为生成新树而传入的最小值的类型,这使类型系统可以告诉我是否将它们混合使用上。
repmin :: Tree a -> Tree a
repmin = (loop . uncurry) copyRose
copyRose :: Ord a => Tree a -> b -> (Tree b,a)
copyRose (Node x ts) final_min
| (ts',m) <- copyForest x ts final_min
= (Node final_min ts',m)
copyForest :: Ord a => a -> [Tree a] -> b -> ([Tree b],a)
copyForest !m [] _final_min = ([],m)
copyForest !m (t : ts) final_min
| (t',m') <- copyTree m t final_min,(ts',m'') <- copyForest m' ts final_min
= (t' : ts',m'')
copyTree :: Ord a => a -> Tree a -> b -> (Tree b,a)
copyTree !m (Node x ts) final_min
| (ts',m') <- copyForest (min m x) ts final_min
= (Node final_min ts',m')
锻炼:使用ReaderT
来传递全局最小值,使用State
来跟踪最小值,以单子形式重写。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。