Проблемы с пониманием жалобы GHC на неоднозначность

Я пытаюсь создать простой эволюционный алгоритм на 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 не может гарантировать, что вновь созданные геномы приведут к тем же фенотипам, которые он получает, но я не уверен, как решить эту проблему. Могут также быть некоторые проблемы с объявлениями классов, которые я пропустил, поэтому я, вероятно, помог бы найти кого-то лучше меня, чтобы просмотреть его.

1 ответ

Решение

children :: Genome a => [(a,a)], ch1 :: Genome a => [a], и т. д. "Что такое тип данных a? "- спрашивает Хаскелл." Мне нужно проверить, принадлежит ли он Genome Тип класса ".

Ничто в коде не определяет конкретный тип данных aВы работаете только с методами.

Вам нужно поставить a в тип возвращаемого значения, и добавьте Genome a в ограничение, так что это будет определяться сайтом вызова breed:

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

Другие вопросы по тегам