2015-03-19 51 views
3

TypeOperators交戰我試過執行$.,所以我可以清除我的程序中的任何括號(對任何美麗的Lispers都沒有任何攻擊)。這樣做我已經同構複製了定義。首先我試圖只使用$,因爲你不應該需要.它的強大的力量。類型運算符和類型要求的序列

{-# LANGUAGE TypeOperators #-} 
type f $ a = f a 

f :: Int -> IO $ Either String Int 
f n = undefined 

太好了。這編譯和我很滿意。

{-# LANGUAGE TypeOperators #-} 
type f $ a = f a 

f :: Int -> IO $ Maybe $ Either String Int 
f n = undefined 

這應該工作正確嗎?

TyCo.hs:4:18: 
    Expecting one more argument to ‘Maybe’ 
    The second argument of ‘$’ should have kind ‘*’, 
     but ‘Maybe’ has kind ‘* -> *’ 
    In the type signature for ‘f’: 
     f :: Int -> (IO $ Maybe) $ Either String Int 

顯然不是。

{-# LANGUAGE TypeOperators #-} 
type f $ a = f a 
type (f * g) a = f (g a) 

f :: Int -> IO * Maybe $ Either String Int 
f n = undefined 

盲目的希望,我嘗試。

TyCo.hs:5:6: 
    Type synonym ‘*’ should have 3 arguments, but has been given 2 
    In the type signature for ‘f’: 
     f :: Int -> (IO * Maybe) $ Either String In 

在我無知的木訥我提出的問題:WHY不行?

+3

對於第一個示例,它看起來像'$'的關聯性是錯誤的。我認爲在值級別的'$'和在類型級別的'''被認爲是不同的標識符,並且我們沒有爲後者聲明優先級或關聯性。我不知道該怎麼辦,或者如果有辦法。至少要用'infixr'玩一下...... – luqui 2015-03-19 06:25:21

+3

如果你期望這些快捷鍵通常有用,你還應該啓用'PolyKinds'和/或'LiberalTypeSynonyms'。 – luqui 2015-03-19 06:27:19

+2

@ luqui的評論都是正確的。你可以用'infixr 0 $'修復第一個版本,用'LiberalTypeSynonyms'修復第二個版本。 – 2015-03-19 06:59:56

回答

1

第一個問題與$的固定性有關,您可以通過注意括號的放置位置來看到錯誤信息中的符號。 (IO $ Maybe)是部分應用的類型同義詞,導致錯誤。你不能部分應用類型同義詞,因爲它需要比較它們,這相當於比較函數。

LiberalTypeSynonyms只是使GHC解包類型的同義詞它之前的類型檢查,即(IO * Maybe) $ Either String Int變得(IO (Maybe (Either String Int)))然後它鍵入的檢查。這意味着*不再部分應用,並且程序編譯。