此问题使用http://hackage.haskell.org/package/recursion-schemes-4.0/docs/Data-Functor-Foldable.html
中的概念/导入我正在尝试将其扩展为通过一个catamorphism线程给定monad。这是我正在尝试编译的代码:
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
(感谢Antal)。多年来我一直在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
答案 0 :(得分:3)
Base t
是一个类型系列,因此GHC无法从t
了解Base t
。如果不提及distM
,就无法让t
工作。