我正在尝试创建一个简单的 Haskell 进化算法,并且我正在尝试使其尽可能通用。这最初是我用 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
我不完全确定我理解错误,我认为因为两者mom
都dad
属于类Phenotype
,这意味着它们必须支持一种genome
方法,这应该不是问题。我可以看到的一个问题是 GHC 无法确保新创建的基因组会产生与它接收到的相同的表型,但我不确定如何解决这个问题。我忽略的类声明也可能存在一些问题,所以我可能会帮助让比我更好的人来查看它。