2015-10-26 122 views
2

我剛剛用Haskell創建了一個類,但是我的某個實例有問題。我創建了這個類:非法實例聲明

class Symbol a where 
    nameSym :: a -> String 

這些實例:

instance Symbol Double where 
    nameSym db = show db 

instance Symbol String where 
    nameSym str = str 

但在編譯的時候,我得到了以下錯誤消息:

Illegal instance declaration for `Symbol String' 
    (All instance types must be of the form (T t1 ... tn) 
    where T is not a synonym. 
In the instance declaration for `Symbol String' 

你知道是什麼問題?

+1

字符串是一個類型的同義詞,你可以使用[Char]或者一些允許實例中的類型同義詞的編譯器選項。 – Ingo

+2

按照GHC的建議啓用'FlexibleInstances'。這種擴展是無害的,很久以來已被許多圖書館使用。 – chi

+0

'[Char]'在默認規則下也不是有效的實例頭 - 你仍然需要'FlexibleInstances'。 – user2407038

回答

3

可以使用雜注:

{-# LANGUAGE FlexibleInstances #-} 

在源文件的頭。

+2

這個答案提供了一個解決方案,但你能解釋問題的根源嗎? – AJFarmar

5

的問題是,String是一種類型的別名[Char]和Haskell的98規範不允許對類型別名來定義實例。

{-# LANGUAGE TypeSynonymInstances #-} 

然而,仍然不會讓你編譯程序作爲哈斯克爾98也不允許[SomeConcreteType]實例(僅適用於[a]實例:這可以通過在文件的頭部添加此得到解決是允許的 - 感謝Ørjan指出這一點),而在Haskell 98中存在一個解決方法而不使用語言編譯指示,解決這個問題的最簡單方法(也是完全安全和慣用的)是添加以下編譯指示:

{-# LANGUAGE FlexibleInstances #-} 

- 這也使TypeSynonymInstances所以你不需要保留這兩個編譯指示。

+2

Haskell 98和Haskell 2010都允許'[a]'的實例。只是'a'實際上必須是一個類型變量。 –

+0

哎呀,我怕我在那裏犯了一個錯誤;謝謝! –