Ранее я определил функцию, которая берет список Maybe
и превращает его в Maybe
списка, например так:
floop :: [Maybe a] -> Maybe [a]
floop [] = Just []
floop (Nothing:_) = Nothing
floop (Just x:xs) = fmap (x:) $ floop xs
Теперь я хочу переопределить его, чтобы он был совместим с большим классом контейнеров, а не только со списками, и я обнаружил, что он должен реализовать функции foldr
, mappend
, mempty
, fmap
и pure
; поэтому я полагаю, что следующая строка типа будет уместной:
floop :: (Foldable t, Functor t, Monoid t) => t (Maybe a) -> Maybe (t a)
Поскольку (я думаю) это гарантирует, что эти функции реализованы для данного контейнера, однако это приводит к следующей ошибке:
Expecting one more argument to ‘t’
The first argument of ‘Monoid’ should have kind ‘*’,
but ‘t’ has kind ‘* -> *’
In the type signature for ‘floop'’:
floop' :: (Foldable t, Functor t, Monoid t) =>
t (Maybe a) -> Maybe (t a)
Изучив его, я обнаружил, что тип Monoid
отличается от вида Functor
и Foldable
, но я не понимаю, почему это так, и как исправить ошибку.
Кому интересно, вот текущая реализация:
floop :: (Foldable t, Functor t, Monoid t) => t (Maybe a) -> Maybe (t a)
floop xs = let
f :: (Foldable t, Functor t, Monoid t) => Maybe a -> Maybe (t a) -> Maybe (t a)
f Nothing _ = Nothing
f (Just x) ys = fmap (mappend $ pure x) ys
in
foldr f (Just mempty) xs
Примечание. Мне сообщили, что это уже существует как встроенная функция (sequence
), но я намерен реализовать ее в качестве учебного упражнения.
floop
со встроенным обобщением, я предлагаю взглянуть на более общийsequenceA
вместоsequence
. - person duplode   schedule 01.02.2017Alternative
,MonadPlus
иMonoid
, которые вы, возможно, захотите проверить. Я дал ссылку именно на этот вопрос, потому что он действительно краток и более четко связан с вашей конкретной проблемой.) - person duplode   schedule 01.02.2017Monoid t
. Я не понимал, чтоMonoid a
- это "конкретный" тип, а не конструктор типа, такой какFoldable t
. - person Zoey Hewll   schedule 02.02.2017Monoid t
наMonoid (t a)
везде (и обновивFunctor t
доApplicative t
везде, но это не имеет отношения к вашему фактическому вопросу). - person Daniel Wagner   schedule 02.02.2017Functor
. Я используюfmap
наMaybe
, а не наt
- person Zoey Hewll   schedule 02.02.2017