XTypeOperators扩展名不能用作杂注 [英] XTypeOperators extension doesn't work as pragma

查看:103
本文介绍了XTypeOperators扩展名不能用作杂注的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆