2013-04-02 90 views
2

我試圖創建一個簡單的Haskell進化算法,我試圖使它儘可能通用GHC投訴。這原本是我在Python中解決的一個任務,當我有更多時間並在Haskell中解決時,我想回到這個任務。該任務需要的代碼非常靈活,我試圖在我的初步Haskell實現中重新創建。無法理解歧義

在下面的代碼,你可以看到錯誤GHC是給我:

Ambiguous type variable 'a0' in the constraint: 
    (Genome a0) arising from a use of 'crossover' 
Probable fix: add a type signature that fixes these type variable(s) 
In the expression: crossover cross (genome dad) (genome mom) 
In the first argument of 'mapM', namely 
    '(\ (dad, mom) -> crossover cross (genome dad) (genome mom))' 
In a stmt of a 'do' block: 
    children <- mapM 
       (\ (dad, mom) -> crossover cross (genome dad) (genome mom)) parents 

我有下面的類聲明:

class (Eq a, Show a) => Genome a where 
     crossover  :: (Fractional b) => b -> a -> a -> IO (a, a) 
     mutate   :: (Fractional b) => b -> a -> IO a 
     develop   :: (Phenotype b) => a -> b 

class (Eq a, Show a) => Phenotype a where 
     --In case of Coevolution where each phenotype needs to be compared to every other in the population 
    fitness   :: [a] -> a -> Int 
    genome   :: (Genome b) => a -> b 

的代碼是給我的問題是:

breed :: (Phenotype b) => [(b, b)] -> Double -> Double -> IO [b] 
breed parents cross mute = do 
     children <- mapM (\ (dad, mom) -> crossover cross (genome dad) (genome mom)) parents 
     let ch1 = map fst children ++ map snd children 
     mutated <- mapM (mutate mute) ch1 
     return $ map develop mutated 

我不能完全肯定我理解的錯誤,我會認爲,因爲這兩個momdadPhenotype類的,這意味着他們必須支持genome方法這不應該是一個問題。我可以看到的一個問題是,GHC不能確保新創建的基因組會產生與它接收的相同的表型,但我不知道如何解決這個問題。我忽略了類聲明也可能存在一些問題,所以我可能會幫助讓某人比我更好地查看它。

+0

問題從源頭根源在於調用品種功能。從哪裏調用品種函數的'b'類型是什麼? – mhitza

+0

@mhitza如果我理解正確,源文件中'b'的類型也應該只是類表型。完整的代碼在這裏http://hpaste.org/85037 – Nordmoen

回答

4

children :: Genome a => [(a,a)]ch1 :: Genome a => [a]。等等。「什麼數據類型是a?」 - 問Haskell。 「我需要檢查它屬於Genome類型類」。

在代碼沒有確定的a具體數據類型,則僅與方法操作。

你需要把a到返回類型也一樣,並添加Genome a到約束,使之由breed呼叫現場情況而定:

breed :: (Phenotype b, Genome a) => [(b, b)] -> Double -> Double -> (Something a,IO [b])

+1

嗯,我想我理解這個問題,但我仍然不明白爲什麼它是一個問題。不應該認爲'ch1 :: Genome a => [a]'足以確定'ch1'的所有成員必須支持'mutate'和'develop',這將確保我得到一個'Phenotype'從方法返回。我的想法是,無論是品種還是調用者都需要知道中介向下進入「Genome」,只要它知道它正在獲得一個適當的「Phenotype」,這可能是完全錯誤的 – Nordmoen

+1

@Nordmoen ch1的每個成員都是輸入必須屬於基因組類型類的'a'。什麼是具體的數據類型?未知。我們知道它必須支持操作,但是操作是什麼?我們必須執行它。你描述的是這兩種類型的多態函數,一個是基因組,另一個是表型。 *根據您的類型簽名,究竟哪一種* Phenotype,由「品種」的調用網站確定。對於基因組來說不是這樣。如果您希望特定的基因組保持隱藏狀態,則必須在'品種'中提供特定的基因組類型。或者,也可以在基因組中使'多樣性'多態。 –

+0

啊我明白了,我對類和方法之間的交互的理解是完全沒有關係的。然而,我想知道如果除了必須返回某些「基因組」,還有其他方法嗎?他們只會被拋棄,因爲上述所有人都只對它生產的「Phenotypes」感興趣 – Nordmoen