2012-01-31 43 views
5

Wen使用函數依賴關係時,我經常碰到覆蓋條件。可以用UndecidableInstances來解除它,但我通常儘量遠離那個擴展。如何解決函數依賴的覆蓋條件而不使用-XUndecidableInstances

這裏是一個有些人爲的例子,在不UndecidableInstances工作的:

{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-} 

data Result = Result String 
    deriving (Eq, Show) 

data Arguments a b = Arguments a b 

class Applyable a b | a -> b where 
    apply :: a -> b -> Result 

instance Applyable (Arguments a b) (a -> b -> Result) where 
    (Arguments a b) `apply` f = f a b 

當我做的結果類型更通用的,所述覆蓋條件失敗(因此需要UndecidableInstances):

{-# Language MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances #-} 

data Result a = Result a 
    deriving (Eq, Show) 

data Arguments a b = Arguments a b 

class Applyable a b c | a -> b c where 
    apply :: a -> b -> Result c 

instance Applyable (Arguments a b) (a -> b -> Result c) c where 
    (Arguments a b) `apply` f = f a b 

我認爲因爲bc都是由a決定的,所以更通用的代碼不應該引起任何問題,所以我的問題:

  1. 是否有使用UndecidableInstances這裏
  2. 我可以在上面的場景模擬任何可能出現的問題,而不依賴於UndecidableInstances(可能與類型的家庭?)
+7

沒有什麼大的理由遠離'UndecidableInstances'。可能發生的最糟糕的事情是類型檢查器開始循環(並且告訴你這個問題,我想)。你可以使覆蓋條件變得越來越聰明,但它不會做你想做的所有事情,因爲這是不可判定的。 – augustss 2012-01-31 08:29:10

+0

c在這裏如何確定? – Saizan 2012-02-19 21:54:40

回答

7

有沒有很大的原因來自UndecidableInstances遠離。可能發生的最糟糕的事情是類型檢查器開始循環(並且告訴你這個問題,我想)。你可以使覆蓋條件變得越來越聰明,但它不會做你想做的所有事情,因爲這是不可判定的。