Возникла проблема с расширением Data.Functor.Foldable
В этом вопросе используются понятия / импорт из http://hackage.haskell.org/package/recursion-schemes-4.0/docs/Data-Functor-Foldable.html
Я пытаюсь расширить это, чтобы пронизать данную монаду через катаморфизм. Вот код, который я пытаюсь скомпилировать:
class (Monad m, Foldable t) => FoldableM m t where
distM :: Base t (m a) -> m (Base t a)
cataM :: (Base t a -> m a) -> t -> m a
cataM f = join . liftM f . distM . fmap (cataM f) . project
Но призыв к distM
в cataM
по какой-то причине не могу понять, чтобы использовать тот же t
,
Я получаю ошибку:
Expected type: Base t (m a) -> m (Base t a)
Actual type: Base t0 (m a) -> m (Base t0 a)
Я сделал код немного менее сексуальным и немного легче для отладки здесь:
cataM :: forall a . (Base t a -> m a) -> t -> m a
cataM f t = join d
where
a :: Base t t
a = project t
b :: Base t (m a)
b = fmap (cataM f) a
g :: Base t (m a) -> m (Base t a)
g = distM
c :: m (Base t a)
c = g b
d :: m (m a)
d = liftM f c
Определение g
это то, что вызывает проблему.
РЕДАКТИРОВАТЬ: проблема, как я понимаю, в том, что, когда он вызывает distM
это только имеет Base t
выводить тип из, поэтому он не может работать t
, Это расстраивает, так как я знаю, что t
Я хочу использовать. На самом деле, я думаю, что если бы я мог предоставить аргументы типа distM
вручную это решило бы проблему, но я не думаю, что это возможно.
Вот решение, но я не доволен им:
class (Monad m, Foldable t) => FoldableM m t where
distM :: t -> Base t (m a) -> m (Base t a)
cataM :: forall a . (Base t a -> m a) -> t -> m a
cataM f = join . liftM f . distM (undefined :: t) . fmap (cataM f) . project
РЕДАКТИРОВАТЬ 2: круто, чтобы узнать о Proxy
(спасибо, Антал). Я был на Хаскеллинге уже много лет и только что узнал еще одну новую вещь. Я люблю этот язык. Я использую решение:
class (Monad m, Foldable t) => FoldableM m t where
distM :: proxy t -> Base t (m a) -> m (Base t a)
cataM :: forall a . (Base t a -> m a) -> t -> m a
cataM f = join . liftM f . distM (Proxy :: Proxy t) . fmap (cataM f) . project
1 ответ
Base t
это типовая семья, поэтому GHC не может знать t
от Base t
, Там нет способа получить distM
работать без упоминания t
,