为什么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
的返回类型是调用tc
的结果,这意味着它必须具有与c
相同的类型。这个功能真的很聪明!