我正在试图了解这个来自Haskell recursion-schemes包的非常抽象的递归函数是如何工作的(或者,实际上,它是如何工作的!)--来自这个文件
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?在哈斯克尔,我认为逃避专横的单身汉是不可能的!
我首先将源文件加载到Intero中,以尝试使用它的类型到点功能,但这尝试了失败。
然后,我使用GHCi使用cabal repl将其加载到cabal repl中,并尝试一次一个地遍历组合函数中的类型,通过注释出定义中的各种位数,使用GHCi帮助进行类型推断。然而,当我到达fmap时,我无法想出该注释什么,因为如果我取消对递归a调用的注释,但是注释掉了其他东西,我认为它可能甚至不会编译,因为部分注释掉的a定义没有正确的类型。
发布于 2016-09-25 12:54:04
通过在(.:: _)中包围它们,我设法让ghci告诉我子表达式的类型。
事实证明,诀窍是,“分布规律”k允许您将单块插入临时Base类型,然后embed方法允许您放弃临时Base类型并返回到t。如果t的具体类型确实没有提到IO,那么就不可能(安全地)为IO monad编写这样一个k。所以这里没有魔法--也就是没有办法用这个函数来逃避那些无法避免的单数,比如IO。
https://stackoverflow.com/questions/39685494
复制相似问题