XTypeOperators扩展名不能用作杂注 [英] XTypeOperators extension doesn't work as pragma
问题描述
我使用GHCi 7.0.3和以下程序来实现类型级别列表:
{ - #LANGUAGE TypeOperators# - }
数据True
数据False
- List
数据无
数据Cons x xs
- 类型级infix操作符必须以':'开始
data x ::: xs
infixr 5 ::: - 将优先级设置为5(紧)
它会编译,但是当我测试它时:
:t(undefined :: True ::: Nil)
(当转换为输入 True ::: Nil
?)时, undefined
的类型是什么?
非法运算符`:::'类型为True :::无'
使用-XTypeOperators允许运算符类型为
事实上,当我启动带有国旗的GHCi时
-XTypeOperators
我得到预期的结果:
(undefined :: Tru e ::: Nil):: True ::: Nil
我的问题是:为什么不等价的编译指示工作:
$ $ p $ { - #LANGUAGE TypeOperators# - }
编辑:如果编译指令不会扩展到GHCi环境,我试过这个程序:
class And b1 b2 b | b1 b2 - > b其中
和f :: b1 - > b2 - > b
- 真值表
实例和True True True其中andf = undefined
实例和True False False其中andf = undefined
实例和False True False where andf = undefined
实例和False False False其中andf = undefined
它需要以下编译指示:
{ - #LANGUAGE MultiParamTypeClasses# - }
{ - #LANGUAGE FunctionalDependencies# - }
code>
但是一旦编译完成,我可以在GHCi中使用它:
*主> :t和f(undefined :: True)(undefined :: False)
andf(undefined :: True)(undefined :: False):: False
我想在列表案例中,解释器甚至不能用类型级别的操作符 :::
来解析表达式。 ,而在多参数类的情况下,命令行是可解析的。但是,想一想,GHCi使用多参数类和函数依赖来执行类型推断,不是吗?这种类型推断是在GHCi中完成的,而不是通过调用编译代码中的某个函数,对吗?
其他答案是纠正有关启用GHCi的扩展,无论是从GHCi提示还是作为启动GHCi时的标志。然而,还有第三种选择 - 您可以创建一个 .ghci
文件,每次启动GHCi时将加载并运行该文件,并使用该文件自动启用扩展。特别是对于像 TypeOperators
这样的东西,启用它几乎没有什么害处,这非常方便。
例如,这里是我现在的样子:
:设置提示符∀x。x⊢
:set - XTypeOperators
import Control.Monad
import Control.Applicative
import Control.Arrow
.ghci
文件会存放在您系统的标准位置用于这些文件中。
回答你的问题:有问题的代码在GHCi中工作的原因大概是因为如果在另一个模块中使用,它使用编译指示导入模块,但是它本身没有启用它。即使导出的定义在没有扩展名的情况下不可能有意义,或者推断了需要它的类型,GHC也能够基于每个模块启用扩展。
GHCi中的区别有点模糊,因为它也将模块的非导出定义放在范围内,但通常情况下,如果从另一个模块使用,任何可以在GHCi提示符下工作的任何东西都可以使用。
I'm using GHCi 7.0.3 with the following program that implements type-level list:
{-# LANGUAGE TypeOperators #-}
data True
data False
-- List
data Nil
data Cons x xs
-- Type-level infix operator must begin with ':'
data x ::: xs
infixr 5 ::: -- set precedence level to 5 (tight)
It compiles, but when I test it with:
:t (undefined :: True:::Nil)
(what's the type of undefined
when cast to type True:::Nil
?) I get this error:
Illegal operator `:::' in type `True ::: Nil'
Use -XTypeOperators to allow operators in types
And indeed, when I start GHCi with the flag
-XTypeOperators
I get the expected result:
(undefined :: True ::: Nil) :: True ::: Nil
My question is: Why doesn't the equivalent pragma work:
{-# LANGUAGE TypeOperators #-}
Edit: If pragmas don't extend to GHCi environment than I have another puzzle. I tried this program:
class And b1 b2 b | b1 b2 -> b where
andf :: b1 -> b2 -> b
-- truth table
instance And True True True where andf = undefined
instance And True False False where andf = undefined
instance And False True False where andf = undefined
instance And False False False where andf = undefined
It required the following pragmas:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
But once compiled, I could use it in GHCi:
*Main> :t andf (undefined::True) (undefined::False)
andf (undefined::True) (undefined::False) :: False
I guess in the list case the interpreter couldn't even parse the expression with type-level operator :::
, whereas in the case of multiparameter classes the command line was parseable. But, come to think of it, GHCi performed type inference using multi-parameter classes and functional dependencies, didn't it? This type inference is done in GHCi, and not by calling some function in the compiled code, right?
The other answers are correct about enabling the extension in GHCi, either from the GHCi prompt or as a flag when starting GHCi. There is a third option, however--you can create a .ghci
file that will be loaded and run every time you start GHCi, and use that to enable the extension automatically. Particularly for things like TypeOperators
, where there's very little harm in having it enabled, it's nicely convenient.
For example, here's what mine looks like right now:
:set prompt "∀x. x ⊢ "
:set -XTypeOperators
import Control.Monad
import Control.Applicative
import Control.Arrow
The .ghci
file goes in whatever your system's standard location is for such files.
To answer your extended question: The code in question works in GHCi roughly because it would also work if used in another module, which imported the module using the pragmas but didn't enable them itself. GHC is more than capable of enabling extensions on a per-module basis, even when the exported definitions couldn't possibly make sense without an extension, or have inferred types that require it.
The distinction is a little fuzzy in GHCi because it also puts non-exported definitions from the module in scope, but in general anything that would work if used from another module will also work at the GHCi prompt.
这篇关于XTypeOperators扩展名不能用作杂注的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!