2011-12-26 59 views
14

我使用GHCI 7.0.3與以下程序實現的類型級列表:XTypeOperators擴展不起作用的編譯

{-# 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) 

它編譯,但是當我測試它:

:t (undefined :: True:::Nil) 

(轉換爲類型True:::Nil當什麼的undefined類型?)我得到這個錯誤:

Illegal operator `:::' in type `True ::: Nil' 
    Use -XTypeOperators to allow operators in types 

事實上,當我開始GHCI旗

-XTypeOperators 

我得到預期的結果:

(undefined :: True ::: Nil) :: True ::: Nil 

我的問題是:爲什麼不等效的編譯工作:

{-# LANGUAGE TypeOperators #-} 

編輯:如果編譯指示不延伸到GHCi環境比我有另一個難題。我想這個方案:

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 

它需要以下編譯:

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE FunctionalDependencies #-} 

但是一旦編譯,我可以在ghci中使用它:

*Main> :t andf (undefined::True) (undefined::False) 
      andf (undefined::True) (undefined::False) :: False 

我想在列表中的情況下解釋程序甚至無法用類型級別的運算符:::解析表達式,而在多參數類的情況下,命令行是可解析的。但是,想一想,GHCi使用多參數類和函數依賴來執行類型推斷,不是嗎?這種類型推斷是在GHCi中完成的,而不是通過調用編譯代碼中的某個函數,對吧?

回答

14

其他答案對GHCi中的擴展是正確的,無論是從GHCi提示還是作爲啓動GHCi時的標誌。然而,還有第三種選擇 - 您可以創建一個.ghci文件,每次啓動GHCi時將加載並運行該文件,並使用該文件自動啓用擴展。尤其對於像TypeOperators這樣的啓動非常有害的地方,它非常方便。

例如,這裏是我的樣子現在:

:set prompt "∀x. x ⊢ " 
:set -XTypeOperators 
import Control.Monad 
import Control.Applicative 
import Control.Arrow 

.ghci文件進去無論你的系統的標準位置是這樣的文件。


要回答你的問題延伸:有問題的代碼GHCI工作大致是因爲它也會如果另一個模塊,其中進口使用編譯指示的模塊,但並沒有使他們自己使用的工作。即使導出的定義在沒有擴展名的情況下不可能有意義,或者推斷了需要它的類型,GHC也能夠基於每個模塊啓用擴展。

GHCi中的區別有點模糊,因爲它也將模塊的非導出定義放在範圍內,但通常情況下,如果從另一個模塊使用,任何可以工作的東西也可以在GHCi提示符下工作。

+1

+1 .ghci文件 – 2011-12-26 20:37:54

7

你的編譯是正確的;問題在於你試圖從GHCi內部使用GHCi,它不會繼承已加載模塊的擴展,但是確實是通過它給GHC的選項來編譯你列出的文件(這是爲什麼它與編譯指示具有相同的效果)。

你應該保持編譯,並且無論是通過-XTypeOperators當你開始GHCI,或加載後使之如下:

GHCi> :set -XTypeOperators 

這可能是非常不可取的,而且在許多恐怕是不可能的例如,例如加載編譯模塊。

4

LANGUAGE編譯指示適用於源文件,它不會傳播到ghci -prompt。由於在項目的多個源文件中可能存在衝突的編譯指示,因此源編譯指示無法默認傳播到ghci -prompt。我可以從*module的提示中得到有效的編譯指示,但我認爲實現這一點是非常有必要的,無論如何,目前爲止還沒有實施,因此您需要將擴展​​名設置爲ghci明確。