【问题标题】:Is it possible to define instances of Data.Foldable with foldr where foldr takes arguments of different types?是否可以使用 foldr 定义 Data.Foldable 的实例,其中 foldr 接受不同类型的参数?
【发布时间】:2017-09-19 20:02:58
【问题描述】:

类型类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 -&gt; a -&gt; a。但是我无法 定义 foldr 函数真正类型为 a -&gt; b -&gt; b 的内容,其中类型为 ab 不一样。

以下代码显示了一个无法编译的示例:

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 定义Foldable 的实例,其中ab 的类型真的不同?

【问题讨论】:

    标签: haskell typeclass


    【解决方案1】:

    问题不在于类型不同。 foldr 的类型与 Foldable 要求的类型不同。它需要是:

    foldr :: (a -> b -> b) -> b -> Tree a -> b
    

    并且那些ab 类型参数必须保留为参数:这对于ab 的所有选择都有效。您不能将它们限制为其他类型类,也不能将其中一个限制为具体的 Int 类型。

    【讨论】:

      【解决方案2】:

      似乎你想要的可以通过使用实际的foldr函数而不是修改它来实现。您不能更改类型类方法的签名,在这种情况下,没有必要。尝试通过提供其类型的合理实现来实现foldr,然后编写一个可以作为第一个参数传递给foldr 的函数addSizefoldr addSize 0 会有你想要的行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 2014-06-18
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多