模板Haskell中准引号内的类型检查
我正在努力熟悉,让我惊讶的是,下面的代码是在模板Haskell中准引号内的类型检查,haskell,types,metaprogramming,type-systems,Haskell,Types,Metaprogramming,Type Systems,我正在努力熟悉,让我惊讶的是,下面的代码是在ghc(版本6.10.4)下编译的 main=do 让 y=[|“你好”+1 |] putStr“” 这对我来说意味着在准引号中没有类型检查。这不是我在阅读Haskell模板上的原始内容后所期望的。此外,以下程序不编译 main = do let y = [| "hello" && True |] putStr "" main=do 让 y=[|“你好”&&True] putStr“” 这是怎么回事?模板
ghc
(版本6.10.4)下编译的
main=do
让
y=[|“你好”+1 |]
putStr“”
这对我来说意味着在准引号中没有类型检查。这不是我在阅读Haskell模板上的原始内容后所期望的。此外,以下程序不编译
main = do
let
y = [| "hello" && True |]
putStr ""
main=do
让
y=[|“你好”&&True]
putStr“”
这是怎么回事?模板Haskell有两个主要操作:
- 提升:
[| |]
- 拼接
$()
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
main = print =<< runQ [| "hello" + 1 |]
{-#语言模板haskell}
导入语言.Haskell.TH
main=print=:t[|“hello”+1 |]
[|“你好”+1 |]::Q Exp
*Main>$([|“hello”+1 |])
:1:4:
没有(Num[Char]的实例)
源于字面上的“1”
正如我们所料。因此,是的,表达式是经过类型检查的,但在后期,当拼接回程序时。看起来GHC确实对所有引用进行了类型检查,但假设所有生成的实例约束都可以得到满足 在此代码中:
main = do
let
y = [| "hello" + 1 |]
putStr ""
main = do
let
y = [| "hello" && True |]
putStr ""
在假设有Num字符串实例的情况下,y括号是可键入的。由于GHC不能确定在插入y之前不会引入这样的实例,所以它不会给出类型错误
在此代码中:
main = do
let
y = [| "hello" + 1 |]
putStr ""
main = do
let
y = [| "hello" && True |]
putStr ""
无论您设置的是什么实例环境,y都无法成功拼接
这只是Template Haskell的类型检查机制过于宽松的一个例子——更多的例子将在Simon PJ的博客文章中讨论,他在文章中建议更改为根本不检查任何引用。谢谢你,Don。我仍然不明白的是为什么[|“hello”+1 |]类型检查,但[|“hello”&&1 |]不检查(即使没有拼接)。佩顿·琼斯(Peyton Jones)的原稿在第66页上写道:“类型检查术语e立即检测到任何内部类型不一致;例如,[|‘a’+True]将立即被拒绝”。好吧,这就解释了这一点。谢谢你,麦克斯!