Une fois, j'ai trébuché sur le suivant. Répondre à cette question, j'ai d'abord essayé ce code:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
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) => a -> b
class (Eq a, Show a) => Phenotype a b | a -> b 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 -- here, the problem
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
Et j'ai obtenu une erreur de compilation et d'une suggestion GHCi ajouter l' FlexibleContexts
option. Quand je l'ai fait, elle a établi OK. Mais ce n'était pas une bonne chose à faire, que la contrainte de la déclaration introduit nouveau champ d'application pour les variables de type, et b
en genome
's type de signature est devenu complètement étranger à la une dans le type de classe; pourtant, FlexibleContexts
a fourni une couverture pour ce.
Avec la contrainte spécifiée correctement le type le niveau de la classe,
class (Eq a, Show a, Genome b) => Phenotype a b | a -> b where
-- In case of Coevolution where each phenotype needs to be compared to
-- every other in the population
fitness :: [a] -> a -> Int
genome :: a -> b
il est passé de la compilation sans exiger de l' FlexibleContexts
option.