树型可折叠,"value of instance is undefined here, so this reference is not allowed"
Foldable for Tree type, "value of instance is undefined here, so this reference is not allowed"
定义如下简单树结构后
data Tree a = Leaf | Branch (Tree a) a (Tree a)
我尝试为其定义一个 Foldable
实例,仅定义 foldMap
并使用 foldrDefault
和 foldlDefault
函数:
instance treeFoldableInstance :: Foldable Tree where
foldr = foldrDefault
foldl = foldlDefault
foldMap f Leaf = mempty
foldMap f (Branch left a right) = foldMap f left <> (f a) <> foldMap f right
然而,这会导致:
The value of treeFoldableInstance is undefined here, so this reference is not allowed.
当我明确定义 foldl
和 foldr
时,它会编译。这个错误的文档告诉我懒惰,但这在这里如何应用?
出现这种情况是因为使用 foldlDefault
和 foldrDefault
需要您尝试构建的字典,而且由于 PureScript 是严格评估的,所以这是不可能的。
这里最简单的解决方法可能是尝试类似的方法:
instance treeFoldableInstance :: Foldable Tree where
foldr f = foldrDefault f
foldl f = foldlDefault f
foldMap f Leaf = mempty
foldMap f (Branch left a right) = foldMap f left <> (f a) <> foldMap f right
通过 eta 扩展 foldr
和 foldl
定义,它延迟了自我引用,因为脱糖代码变成了这样的:
foldr = \f -> foldrDefault treeFoldableInstance f
所以对treeFoldableInstance
的引用只在f
传入之后才被求值,而不是在treeFoldableInstance
.
的声明期间求值
定义如下简单树结构后
data Tree a = Leaf | Branch (Tree a) a (Tree a)
我尝试为其定义一个 Foldable
实例,仅定义 foldMap
并使用 foldrDefault
和 foldlDefault
函数:
instance treeFoldableInstance :: Foldable Tree where
foldr = foldrDefault
foldl = foldlDefault
foldMap f Leaf = mempty
foldMap f (Branch left a right) = foldMap f left <> (f a) <> foldMap f right
然而,这会导致:
The value of treeFoldableInstance is undefined here, so this reference is not allowed.
当我明确定义 foldl
和 foldr
时,它会编译。这个错误的文档告诉我懒惰,但这在这里如何应用?
出现这种情况是因为使用 foldlDefault
和 foldrDefault
需要您尝试构建的字典,而且由于 PureScript 是严格评估的,所以这是不可能的。
这里最简单的解决方法可能是尝试类似的方法:
instance treeFoldableInstance :: Foldable Tree where
foldr f = foldrDefault f
foldl f = foldlDefault f
foldMap f Leaf = mempty
foldMap f (Branch left a right) = foldMap f left <> (f a) <> foldMap f right
通过 eta 扩展 foldr
和 foldl
定义,它延迟了自我引用,因为脱糖代码变成了这样的:
foldr = \f -> foldrDefault treeFoldableInstance f
所以对treeFoldableInstance
的引用只在f
传入之后才被求值,而不是在treeFoldableInstance
.