Haskell 为什么类型签名看起来像这样?(将教堂编号转换为整数)
我正在学习Haskell,并试图编写一个函数,将Church数字转换为Int。我的代码只有在不编写类型签名的情况下才能工作Haskell 为什么类型签名看起来像这样?(将教堂编号转换为整数),haskell,types,type-signature,Haskell,Types,Type Signature,我正在学习Haskell,并试图编写一个函数,将Church数字转换为Int。我的代码只有在不编写类型签名的情况下才能工作 type Church a = (a -> a) -> a -> a zero :: Church a zero s z = z c2i :: Church a -> Int -- This line fails c2i x = x (+1) 0 我使用:t c2i c2i :: (Num a1, Num a) => ((a ->
type Church a = (a -> a) -> a -> a
zero :: Church a
zero s z = z
c2i :: Church a -> Int -- This line fails
c2i x = x (+1) 0
我使用:t c2i
c2i :: (Num a1, Num a) => ((a -> a) -> a1 -> t) -> t
但是我想知道为什么会这样?如果你在
c2i
签名中使用a
,那么它必须与任何a
一起工作。
换句话说,a
由函数的调用者选择。
具体地说,它必须与
c2i :: Church String -> Int
-- that is
c2i :: ((String -> String) -> String -> String) -> Int
由于当a=String
时代码不起作用,因此多态类型无效
如果不添加类型,编译器可以推断出使代码工作的某种类型。更简单的类型可以是:
c2i :: Church Int -> Int
或者,在启用一些扩展之后
c2i :: (forall a. Church a) -> Int
在后一种情况下,我们指定a
由c2i
选择,而不是由调用方选择。相反,调用者必须传递一个必须具有多态类型的参数:即,它必须为所有a
传递Church a
,而不仅仅是Church字符串
或者,你甚至可以声明
type Church = forall a . (a->a)->a->a
只传递多态性值。但是
类型
声明会让人很痛苦。相关的