为什么Haskell中允许这种递归(?)类型?

为什么Haskell中允许这种递归(?)类型?,haskell,types,type-inference,Haskell,Types,Type Inference,我已经看到了以下定义: getCC :: t -> ContT r m (t, t -> ContT r m b) getCC x0 = callCC (\c -> let f x = c (x, f) in return (x0, f)) 但是如果有人隐藏了getCC的类型声明,我将无法找到它 f的类型是什么 嗯,f是一个函数,它接受t并返回contr m(t,*something*)。但是某些东西的类型必须与f相同 所以f::contrm(t,contrm(t,contr

我已经看到了以下定义:

getCC :: t -> ContT r m (t, t -> ContT r m b)
getCC x0 = callCC (\c -> let f x = c (x, f) in return (x0, f))
但是如果有人隐藏了
getCC
的类型声明,我将无法找到它

f
的类型是什么

嗯,
f
是一个函数,它接受
t
并返回
contr m(t,*something*)
。但是某些东西的类型必须与
f
相同

所以
f::contrm(t,contrm(t,contrm(t,contrm(t,…))


为什么/如何
ghc
推断
f::t->Cont r m b)

类型中没有递归:

{-# LANGUAGE ScopedTypeVariables #-}

import Control.Monad.Trans.Cont

getCC :: t -> ContT r m (t, t -> ContT r m b)
getCC x0 = callCC (\(c :: (t, t -> ContT r m b) -> ContT r m b) 
                   -> let f :: t -> ContT r m b
                          f x = c (x, f)
                      in return (x0, f))

我还没有完全解决这个问题,但是
f
是被绑定的,所以它实际上可以是多态的。
f
不仅仅是返回
(x,f)
,它首先应用
c
。即使是一个列表
数据列表a=Nil | Cons a(列表a)
也是递归的,并且没有什么问题。弗兰基,我没有很好地表达它。谢谢你的更正。我实际上的意思是,
f
似乎是无限递归的(实际上不是)。我有一个GHC禁止的无限递归的例子:
callCC$\c->returnc
。没错。理解这一点的关键是
c
的类型,这是
callCC:((a->conttrmb)->conttrma)->conttrma类型的结果
c
返回
conttrmb
,其中
b
独立于
a
fx
的返回类型是调用t
c
的结果,这意味着它必须具有与
c
相同的类型。这个功能真的很聪明!