【问题标题】:How does gpostpro "escape from the monad"?gpostpro 如何“逃离单子”?
【发布时间】:2017-02-02 18:33:47
【问题描述】:

我试图了解 Haskell recursion-schemes 包中这个非常抽象的递归函数是如何工作的(或者,实际上,它的作用!) - 来自 this file

class Functor (Base t) => Corecursive t where

  [...]

  -- | A generalized postpromorphism
  gpostpro
    :: (Recursive t, Monad m)
    => (forall b. m (Base t b) -> Base t (m b)) -- distributive law
    -> (forall c. Base t c -> Base t c)         -- natural transformation
    -> (a -> Base t (m a))                      -- a (Base t)-m-coalgebra
    -> a                                        -- seed
    -> t
  gpostpro k e g = a . return where a = embed . fmap (ana (e . project) . a . join) . k . liftM g

我特别想了解的是:它如何应用g函数,它提到了monad类型构造函数m,然后返回一个t类型的值,它没有提到或依赖m?我认为在 Haskell 中从任意 monad 中逃脱是不可能的!

我首先将源文件加载到 Intero 以尝试使用它的 type-at-point 功能,但那次尝试failed

然后我使用cabal repl 将其加载到 GHCi 中,并尝试通过组合函数一次一个地跟踪类型,使用 GHCi 通过注释掉定义的各个位来帮助进行类型推断。但是,当我到达 fmap 时,我无法确定要注释掉的内容,因为如果我取消注释递归 a 调用但注释掉其他内容,我认为它甚至可能无法编译,因为部分- a 的注释定义 类型不正确。

【问题讨论】:

  • 你可以用_代替任何表达式来询问GHC它的类型。
  • 还有。转义:t 属于Recursive 类,这意味着它具有* -> * 种类。这暗示 gpospro 返回类型没有转义任何东西,而是被包装成某种东西。这可能是一个单子。
  • @arrowd 如果是这种情况,上面的类型签名是不可能的,因为你不能有一个类型为 * -> * 的返回类型。

标签: haskell recursion monads recursion-schemes


【解决方案1】:

我设法让 ghci 告诉我子表达式的类型,方法是用 (...:: _) 包围它们。

事实证明,诀窍是,“分配法则”k 允许您将 monad 推入临时 Base 类型,然后 embed 方法允许您免除临时 Base 类型并返回t。如果确实具体类型t 没有提到IO,那么就不可能为IO monad 编写这样的k(安全地),例如。所以这里没有魔法——也就是说,没有办法使用这个函数来逃避单子,否则这些单子是无法逃避的,比如 IO。

【讨论】:

  • 然后将自己的答案标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-14
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多