【问题标题】:Having an issue extending Data.Functor.Foldable扩展 Data.Functor.Foldable 时遇到问题
【发布时间】:2013-11-19 15:52:09
【问题描述】:

本题使用来自http://hackage.haskell.org/package/recursion-schemes-4.0/docs/Data-Functor-Foldable.html的概念/导入

我正在尝试扩展它以使给定的 monad 通过 catamorphism。这是我正在尝试编译的代码:

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

但是由于某种原因,在cataM 中对distM 的调用无法确定使用相同的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)。我已经使用 Haskell 多年了,刚刚学到了另一个新东西。我喜欢这种语言。我正在使用的解决方案是:

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吗?
  • 不幸的是:(类型变量t 已经被限定了范围,因为我们处于类型类定义中。

标签: haskell recursion-schemes


【解决方案1】:

Base t 是一个类型族,所以 GHC 无法从 Base t 中知道 t。如果不提及t,就无法让distM 工作。

【讨论】:

  • 没有办法吗? :( 我想我必须将t 添加到distM 作为幽灵参数。烦人。
  • @Will:问题是Base可能不是单射的;考虑如果Base S1 T1 ~ ABase S2 T2 ~ A 会发生什么。此外,您可以使用Proxy 方法明确表明该参数仅用于输入(可能使用-XKindPolymorphism):data Proxy t = Proxy,然后是distM :: Proxy t -> ...
  • 如果您使用代理,也许使用签名distM :: g t -> ... 而不是Proxy t?周围有几种不同的代理,这将适用于所有代理,而不是仅限于一个特定的代理。
猜你喜欢
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 2019-10-16
相关资源
最近更新 更多