我试图理解Haskell DECLARE @xml xml;
SET @xml =
N'<root>
<Id>68890</Id>
<Id>68900</Id>
</root>';
SELECT
replicateIdXml.replicateIds.value('.','bigint') as id
FROM @xml.nodes('/root/Id') AS replicateIdXml (replicateIds)
包中这个非常抽象的递归函数是如何工作的(或者,实际上它是什么!) - 来自this file:
recursion-schemes
特别是,我想要理解的是:它如何应用提到monad类型构造函数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
的{{1}}函数,但随后返回g
类型的值,哪个没有提及或依赖m
?我认为在Haskell中逃避任意monad是不可能的!
我首先将源文件加载到Intero中以尝试使用其类型转换功能,但尝试failed。
然后我使用t
将其加载到GHCi中,并尝试通过组合函数一次一个地跟踪类型,使用GHCi来帮助进行类型推断,通过注释掉定义的各个部分。但是,当我到达m
时,我无法找出要注释的内容,因为如果我取消注释递归cabal repl
调用但注释掉了其他内容,我认为它可能不会#&# 39;甚至编译,因为fmap
的部分注释掉的定义不具备正确的类型。
答案 0 :(得分:2)
我设法让ghci在(
... :: _)
中围绕它们来告诉我子表达式的类型是什么。
事实证明,诀窍是,“分配法则”k
允许你将monad推入临时Base
类型,然后embed
方法允许你省去临时Base
类型并返回t
。如果具体类型t
确实没有提到IO
,那么就不可能为IO monad编写这样的k
(安全)。所以这里没有魔法 - 也就是没有办法使用这个函数来逃避monad,否则这些monad将是不可避免的,比如IO。