Этого вопрос использует понятия/импорт из http://hackage.haskell.org/package/recursion-schemes-4.0/docs/Data-Functor-Foldable.htmlИмея вопрос простирающегося Data.Functor.Foldable
Я пытаюсь распространить эту нить заданных монад через катаморфизм. Вот код, который я пытаюсь скомпилировать:
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
является то, что вызывает проблему.
EDIT: Проблема, поскольку я понимаю, что когда она называет 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
EDIT 2: Прохладный, чтобы узнать о Proxy
(спасибо Антал). Я уже много лет занимаюсь Haskelling и только что узнал еще одну новую вещь. Мне нравится этот язык. Решение я использую:
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
Может быть, вам нужны 'ScopedTypeVariables'? – chaosmasttter
К сожалению, нет :(переменная типа 't' уже определена, потому что мы находимся в определении типа класса. – Will