无法理解GHC对歧义的抱怨

时间:2013-04-02 12:56:14

标签: haskell 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

我不完全确定我理解错误,我认为因为momdad属于Phenotype类,这意味着他们必须支持genome方法这应该不是问题。我可以看到的一个问题是GHC不能确保新创建的基因组会产生与它收到的相同的表型,但我不确定如何解决这个问题。我忽略了类声明可能存在一些问题,所以我可能会帮助一个比我更好的人来查看它。

1 个答案:

答案 0 :(得分:4)

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])