如何将返回 [a] 的函数转换为返回 Monoid 的函数?
How to turn a function returning [a] into a function returning a Monoid?
我正在使用以下函数玩 Haskell return 型多态性:
f :: [a] -> [a]
f [] = mempty
f (x:xs) = [x] <> f xs
显然它什么都不做。我想要做的是修改类型,以便它接受一个列表和 returns 一个 Monoid 容器,其中之一可以是一个列表。我被困在这里是因为 Monoid
采用一种类型参数。我不知道类型是什么:f :: Monoid m => [a] -> ?
这可能吗?
正如您所注意到的,如果没有 a -> m
类型的函数可用,您不能将任意 a
转换为任何特定 Monoid m
的成员。但是没有这样的函数适用于 all Monoid 实例——如果有,它必须在类型类定义中,你可以看到它不存在。
因此,您必须将 f
特化到特定的 Monoid,就像您在此处对 [a]
Monoid 所做的那样;或者除了 [a]
之外还接受转换函数 a -> m
。也就是说,您的类型可能会变成:
combine :: Monoid m => (a -> m) -> [a] -> m
如果我们 ask Hoogle about this type,我们会看到您的函数已经定义(将列表泛化为 Foldable):
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
您可能会发现实施 foldMap
是一个有用的练习,无论是对于一般的可折叠物还是专门用于列表。
正如 @amalloy 所说,您需要一种方法将列表的内容放入 "monoid container" - Monoid class 没有定义这样的东西,因此您的列表内容需要已经构成一个幺半群(在这种情况下,你的函数只是 mconcat
):
f :: Monoid m => [m] -> m
f = mconcat
或者您提供转换器函数(在这种情况下,您将列表的内容转换为您的幺半群,然后执行 mconcat:
f :: Monoid m => (a -> m) -> [a] -> m
f converter = mconcat . fmap converter
我正在使用以下函数玩 Haskell return 型多态性:
f :: [a] -> [a]
f [] = mempty
f (x:xs) = [x] <> f xs
显然它什么都不做。我想要做的是修改类型,以便它接受一个列表和 returns 一个 Monoid 容器,其中之一可以是一个列表。我被困在这里是因为 Monoid
采用一种类型参数。我不知道类型是什么:f :: Monoid m => [a] -> ?
这可能吗?
正如您所注意到的,如果没有 a -> m
类型的函数可用,您不能将任意 a
转换为任何特定 Monoid m
的成员。但是没有这样的函数适用于 all Monoid 实例——如果有,它必须在类型类定义中,你可以看到它不存在。
因此,您必须将 f
特化到特定的 Monoid,就像您在此处对 [a]
Monoid 所做的那样;或者除了 [a]
之外还接受转换函数 a -> m
。也就是说,您的类型可能会变成:
combine :: Monoid m => (a -> m) -> [a] -> m
如果我们 ask Hoogle about this type,我们会看到您的函数已经定义(将列表泛化为 Foldable):
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
您可能会发现实施 foldMap
是一个有用的练习,无论是对于一般的可折叠物还是专门用于列表。
正如 @amalloy 所说,您需要一种方法将列表的内容放入 "monoid container" - Monoid class 没有定义这样的东西,因此您的列表内容需要已经构成一个幺半群(在这种情况下,你的函数只是 mconcat
):
f :: Monoid m => [m] -> m
f = mconcat
或者您提供转换器函数(在这种情况下,您将列表的内容转换为您的幺半群,然后执行 mconcat:
f :: Monoid m => (a -> m) -> [a] -> m
f converter = mconcat . fmap converter