[英]Why does the following haskell code for creating a Foldable instance of Tree result in infinite recursion?
I am trying to write a Foldable instance of the following Tree class I created: 我正在尝试编写以下创建的Tree类的Foldable实例:
data Tree a b = Tree b a [Tree a b]
But I wanted to operate on type 'a' in the definition therefore I made a wrapper data type the flips the types in Tree: 但是我想对定义中的类型“ a”进行操作,因此我将包装数据类型转换为Tree中的类型:
data FlipTree a b = FlipTree (Tree b a)
Now to write the actual definition I came up with the following: 现在编写实际定义,我想到了以下内容:
instance Foldable (FlipTree a) where
foldr f x (FlipTree (Tree _ s [])) = (f s x)
foldr f x (FlipTree (Tree _ s children)) =
let updated_x = (f s x)
tqs = (map (\n -> FlipTree n) children) in
foldl (foldr f) updated_x tqs
But this results in infinite recursion when foldr is called. 但这会在调用foldr时导致无限递归。 I have spent two days and have not been able to figure out the thing that I am doing wrong?
我已经花了两天的时间,仍无法弄清我做错了什么?
this is lpaste link to the code file . 这是指向代码文件的 lpaste链接。 I isolated the code as much as I could.
我尽可能地隔离了代码。 This is another file1 which is read to run the code using the command:
这是另一个file1 ,可使用以下命令读取该文件以运行代码:
runghc code.hs 30000000.0 20000.0 < file1.txt runghc code.hs 30000000.0 20000.0 <file1.txt
Not an answer (the questions premise of infinite looping doesn't seem to be correct) but stylistic advice – too long to comment. 不是答案(无限循环的前提条件似乎并不正确),而是风格上的建议–评论时间太长。
First, you probably want to make this a newtype
(there's no reason to have an extra layer of laziness). 首先,你可能想使这个
newtype
(没有理由有懒惰的一个额外层)。
newtype FlipTree a b = FlipTree (Tree b a)
Second, for an easier understandable solution it tends IMO to be preferrable to implement foldMap
instead of foldr
; 其次,对于一个更容易理解的解决方案,它倾向于使IMO更可取的是实现
foldMap
而不是foldr
; it makes the semantics clearer. 它使语义更清晰。 There are multiple ways to fold over this structure, the most reasonable seems
有多种方法可以折叠此结构,最合理的方法似乎是
foldMap f (FlipTree (Tree _ s [])) = f s
foldMap f (FlipTree (Tree _ s children))
= f s <> foldMap (foldMap f . FlipTree) children
where the outer foldMap
folds over the list of children, using again foldMap
for FlipTree
s as the folding-mapping. 其中,外部
foldMap
折叠在foldMap
列表上,再次将foldMap
用于FlipTree
用作折叠映射。 Now, if you want to manually translate this to the foldr
equivalent, you basically just need to thread through the argument. 现在,如果要手动将其转换为等效的
foldr
,则基本上只需要遍历该参数。
foldr f x (FlipTree (Tree _ s children))
= f s . flip (foldr $ flip (foldr f) . FlipTree) children $ x
Now, possibly that instance doesn't actually give the desired behaviour, so please tell us how you want it to behave! 现在,可能该实例实际上并未提供所需的行为,所以请告诉我们您希望它如何表现!
Turned out the definition is 100% correct. 原来定义是100%正确的。 The unwanted behaviour was being caused by the rest of the code.
不必要的行为是由其余的代码引起的。 But thanks anyway to the stackoverflow community for always being there.
但是无论如何,都要感谢stackoverflow社区一直存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.