类型类Data.Foldable有以下定义:
class Foldable t where
{-# MINIMAL foldMap | foldr #-}
foldMap :: Monoid m => (a -> m) -> t a -> m
foldr :: (a -> b -> b) -> b -> t a -> b
....
<more definitions>最小节表示,我可以只使用foldr函数定义一个实例。在我可以编译的所有示例中,foldr函数都具有a -> a -> a类型。但是,我无法定义foldr函数真正具有a -> b -> b类型的东西,其中a和b类型不同。
下面的代码显示了一个没有编译的示例:
import Data.Foldable
data Tree a = Tree a a | Leaf a
class Size a where
size :: a -> Int
instance Size a => Foldable (Tree a) where
foldr :: a -> Int -> Int
foldr x n = size x + n是否可以用foldr定义一个可折叠的实例,其中a和b类型实际上是不同的?
发布于 2017-09-19 10:55:37
问题不在于类型不同。foldr的类型与Foldable所需的不一样。它必须是:
foldr :: (a -> b -> b) -> b -> Tree a -> b这些a和b类型参数必须保持为参数:这必须适用于a和b的所有选择。您不能将它们限制为其他类型类,也不能将它们中的一个限制为具体的Int类型。
发布于 2017-09-19 12:02:58
您想要的东西似乎可以通过使用实际的foldr函数而不是修改它来实现。您不能更改类型类方法的签名,在这种情况下,没有必要。尝试通过提供其类型的合理实现来实现foldr,然后编写一个可以作为第一个参数传递给foldr的函数addSize。foldr addSize 0会有你想要的行为。
https://stackoverflow.com/questions/46298573
复制相似问题