Как вы заметили, вы не можете превратить произвольный a
в член какого-либо конкретного моноида m
без функции типа a -> m
.Но нет такой функции, которая бы работала для всех Моноидных экземпляров - если бы они были, они должны были бы быть в определении класса типов, и вы можете видеть, что их не существует.
Следовательно, вы должны либо специализировать f
для конкретного моноида, как вы делали здесь для [a]
моноида;или принять функцию преобразования a -> m
в дополнение к [a]
.То есть ваш тип может стать следующим:
combine :: Monoid m => (a -> m) -> [a] -> m
И если мы спросим у Google об этом типе , мы увидим, что ваша функция уже определена (обобщающий список для Foldable):
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
Вы можете найти полезным упражнение для реализации foldMap
, либо для складных таблиц в целом, либо для специализированных списков.