Church-style核心中缺少类型变量会发生什么?

pig*_*ker 18 haskell types

这有点深奥,但令人抓狂.在回答另一个问题时,我注意到这个完全有效的程序

poo :: String -> a -> a
poo _ = id

qoo :: (a -> a) -> String
qoo _ = ""

roo :: String -> String
roo = qoo . poo
Run Code Online (Sandbox Code Playgroud)

a检查过程中,类型变量既未解决也未一般化roo.我想知道GHC的核心语言翻译中会发生什么,这是一种教会风格的System F变体.让我用明确的类型lambdas /\和类型应用程序来解决问题@.

poo :: forall a. [Char] -> a -> a
poo = /\ a -> \ s x -> id @ a

qoo :: forall a. (a -> a) -> [Char]
qoo = /\ a -> \ f -> [] @ Char

roo :: [Char] -> [Char]
roo = (.) @ [Char] @ (? -> ?) @ [Char] (qoo @ ?) (poo @ ?)
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事??如何roo成为有效的核心术语?或者我们真的得到一个神秘的空洞量词,尽管类型签名是什么?

roo :: forall a. [Char] -> [Char]
roo = /\ a -> ...
Run Code Online (Sandbox Code Playgroud)

我刚检查过那个

roo :: forall . String -> String
roo = qoo . poo
Run Code Online (Sandbox Code Playgroud)

通过确定,这可能会或可能不会意味着没有额外量化的东西.

那边发生了什么?

ham*_*mar 17

这是GHC生成的核心(在添加一些NOINLINEpragma之后).

qoo_rbu :: forall a_abz. (a_abz -> a_abz) -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs]
qoo_rbu = \ (@ a_abN) _ -> GHC.Types.[] @ GHC.Types.Char

poo_rbs :: forall a_abA. GHC.Base.String -> a_abA -> a_abA
[GblId, Arity=1]
poo_rbs = \ (@ a_abP) _ -> GHC.Base.id @ a_abP

roo_rbw :: GHC.Base.String -> GHC.Base.String
[GblId]
roo_rbw =
  GHC.Base..
    @ (GHC.Prim.Any -> GHC.Prim.Any)
    @ GHC.Base.String
    @ GHC.Base.String
    (qoo_rbu @ GHC.Prim.Any)
    (poo_rbs @ GHC.Prim.Any)
Run Code Online (Sandbox Code Playgroud)

它似乎GHC.Prim.Any用于多态类型.

文档(强调我的):

类型构造函数Any是一种类型,你可以不安全地强制任何提升类型,然后返回.

  • 它被抬起,因此用指针表示
  • 它并不声称是数据类型,这对代码生成器很重要,因为代码gen可能输入数据值但从不输入函数值.

它还用于在类型检查后实例化非约束类型变量.

将这样的类型替换为非约束类型是有意义的,否则像琐碎的表达式length []会导致模糊的类型错误.

  • 我想这就像我们希望的那样有原则性.参数化对其无害性至关重要.这是一个"不在乎"的假人. (3认同)
  • @ocharles:核心?`ghc -ddump-simpl`. (2认同)