Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 可折叠和幺半群类型_Haskell_Types_Monoids_Foldable - Fatal编程技术网

Haskell 可折叠和幺半群类型

Haskell 可折叠和幺半群类型,haskell,types,monoids,foldable,Haskell,Types,Monoids,Foldable,我正在尝试编写使用幺半群和可折叠函数对列表中的所有元素进行加法和乘法的函数。我设置了一些我认为有效的代码: data Rose a = a :> [Rose a] deriving (Eq, Show) instance Functor Rose where fmap f rose@(a:>b) = (f a :> map (fmap f) b) class Monoid a where mempty :: a (<

我正在尝试编写使用幺半群和可折叠函数对列表中的所有元素进行加法和乘法的函数。我设置了一些我认为有效的代码:

data Rose a = a :> [Rose a]
    deriving (Eq, Show)

instance Functor Rose where
    fmap f rose@(a:>b) = (f a :> map (fmap f) b) 

class Monoid a where
    mempty ::           a
    (<>)   :: a -> a -> a

instance Monoid [a] where
    mempty = []
    (<>)   = (++)

newtype Sum     a = Sum     { unSum     :: a } deriving (Eq, Show)
newtype Product a = Product { unProduct :: a } deriving (Eq, Show)

instance Num a => Monoid (Sum a) where
    mempty           = Sum 0
    Sum n1 <> Sum n2 = Sum (n1 + n2)

instance Num a => Monoid (Product a) where
    mempty                   = Product 1
    Product n1 <> Product n2 = Product (n1 * n2)

class Functor f => Foldable f where
    fold    :: Monoid m =>             f m -> m
    foldMap :: Monoid m => (a -> m) -> f a -> m
    foldMap f a = fold (fmap f a)

instance Foldable [] where
    fold = foldr (<>) mempty

instance Foldable Rose where
    fold (a:>[]) = a <> mempty
    fold (a:>b)  = a <> (fold (map fold b))
错误:

Assignment3.hs:68:14: error:
    * Occurs check: cannot construct the infinite type: a ~ Sum a
    * In the expression: foldMap Sum b
      In an equation for `fsum': fsum b = foldMap Sum b
    * Relevant bindings include
        b :: f a (bound at Assignment3.hs:68:6)
        fsum :: f a -> a (bound at Assignment3.hs:68:1)
   |
68 | fsum b     = foldMap Sum b
   |              ^^^^^^^^^^^^^

Assignment3.hs:69:14: error:
    * Occurs check: cannot construct the infinite type: a ~ Product a
    * In the expression: foldMap Product b
      In an equation for `fproduct': fproduct b = foldMap Product b
    * Relevant bindings include
        b :: f a (bound at Assignment3.hs:69:10)
        fproduct :: f a -> a (bound at Assignment3.hs:69:1)
   |
69 | fproduct b = foldMap Product b
   |              ^^^^^^^^^^^^^^^^^

如果在
折叠式映射中使用
Sum
(或
Product
),则首先将
折叠式
中的项目映射到
Sum
s(或
产品
s)。因此,
fsum
的结果将像您定义的那样是一个
和a
,而不是一个
a

fsum :: (Foldable f, Num a) => f a -> Sum a
fsum b = foldMap Sum b
或在eta降低后:


同样的情况也应该发生在
产品上

您需要添加
unsm
unProduct
作为后处理步骤。
fsum :: (Foldable f, Num a) => f a -> Sum a
fsum b = foldMap Sum b
fsum :: (Foldable f, Num a) => f a -> a
fsum b = unSum (foldMap Sum b)
fsum :: (Foldable f, Num a) => f a -> a
fsum = unSum . foldMap Sum