コードをコンパイルしようとしていた問題を理解した後、この質問 (あいまいさに関するGHCの苦情を理解するのに苦労しました) で、Will Ness は、私が完全に満足していない解決策を避けるために、型クラスを再設計することを提案しました。
問題の型クラスは次のとおりです。
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
Genomes
Haskell で、さまざまなとをサポートする拡張可能な進化的アルゴリズムを作成しようとしていますPhenotypes
。たとえば、1 つGenome
はビット配列、もう 1 つは int のリストである可能性があり、またhttp://en.wikipedia.org/wiki/Colonel_BlottoでPhenotypes
軍隊の動きを表す単なる double のリストとは異なる場合があります。 ANN を表します。
aPhenotype
は a から開発されるためGenome
、使用されるメソッドは完全に互換性がなければならず、1 つのGenome
クラスはPhenotypes
異なる開発メソッドを提供することで複数をサポートできる必要があります (これはコード内で静的に行うことができ、実行時に動的に行う必要はありません)。
これらの型クラスを使用するコードは、ほとんどの場合、使用されている特定の型を幸いなことに認識していないはずです。これが、私が上記の質問をする理由です。
これらの型クラスに適応させたいコードの一部は次のとおりです。
-- |Full generational replacement selection protocol
fullGenerational :: (Phenotype b) =>
(Int -> [b] -> IO [(b, b)]) -> --Selection mechanism
Int -> --Elitism
Int -> --The number of children to create
Double -> --Crossover rate
Double -> --Mutation rate
[b] -> --Population to select from
IO [b] --The new population created
fullGenerational selection e amount cross mute pop = do
parents <- selection (amount - e) pop
next <- breed parents cross mute
return $ next ++ take e reverseSorted
where reverseSorted = reverse $ sortBy (fit pop) pop
breed :: (Phenotype b, Genome a) => [(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
このコードを変更する必要があり、新しい制約を追加する必要があることは理解していますが、型クラスを使用して考えているコードの一部を示したいと思いました。たとえば、上記の完全な世代の置換は、Genome
適切に機能するために基になるものについて何も知る必要はありません。それを繁殖させて新しい子供を作ることができるように、それを生産しPhenotypes
たものを生産できることを知る必要があるだけです。Genome
のコードは、新しいものを設計したり、より優れたものを作成したりしても、変更する必要がないfullGenerational
ように、できるだけ一般的なものにする必要があります。Phenotype
Genome
一般的な EA コード (再利用可能である必要があります) で必要なプロパティを保持しながら、型クラスのあいまいさで発生していた/現在発生している問題を回避するために、上記の型クラスを変更するにはどうすればよいですか?