无法理解GHC对歧义的抱怨 [英] Trouble understanding GHC complaint about ambiguity

查看:141
本文介绍了无法理解GHC对歧义的抱怨的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个简单的Haskell进化算法,我试图尽可能地将它变成一般。这原本是我在Python中解决的一个任务,当我有更多时间并在Haskell中解决时,我想回到这个任务。该作业需要的代码非常灵活,我试图在我的初步Haskell实现中重新创建。



在下面的代码中,您可以看到GHC给我的错误:

 约束中含糊不清的类型变量'a0':
(Genome a0)由于使用'crossover '
可能的修复:添加修复这些类型变量的类型签名
在表达式中:交叉交叉(基因组父亲)(基因组妈妈)
在'mapM'的第一个参数中, ,即
'(\(爸爸,妈妈) - >交叉交叉(基因组爸爸)(基因组妈妈))
在'do'块中:
children (\(爸爸,妈妈) - >交叉交叉(基因组父亲)(基因组妈妈))父母

我有以下类声明:

  class(Eq a,Show a)=> ;基因组a其中
crossover ::(小数b)=> b - > a - > a - > IO(a,a)
mutate ::(Fractional b)=> b - > a - > IO a
develop ::(表型b)=> a - > b

class(Eq a,Show a)=>表型a其中
- 在Coevolution的情况下,每个表型需要与人群中的所有其他表型进行比较
fitness :: [a] - > a - > Int
genome ::(Genome b)=> a - > b

给我这个问题的代码是:

  breed ::(Phenotype b)=> [(b,b)]  - >双 - >双 - > IO [b] 
繁殖父母交叉静音= do
children <-mapM(\(爸爸,妈妈) - >交叉交叉(基因组父亲)(基因组妈妈))父母
let ch1 = map fst children ++ map snd children
mutated< - mapM(mutate mute)ch1
return $ map develop mutated

我并不完全相信我明白错误,我会认为这是因为 mom dad 属于类 Phenotype ,这意味着它们必须支持基因组方法,这不应该成为一个问题。我可以看到的一个问题是,GHC不能确保新创建的基因组会产生与它接收的相同的表型,但我不知道如何解决这个问题。我也忽略了类声明中的一些问题,所以我可能会帮助让别人比我更好地查看它。

解决方案 div>

children :: Genome a => [(A,A)] ch1 :: Genome a => [α] 。等等。什么数据类型是 a ? - 问Haskell。 我需要检查它属于 Genome 类型类。



代码中没有任何内容决定具体数据类型 a ,您只能使用方法操作。



您需要将 a 加入到返回类型中,然后将 Genome a 添加到约束中,以便通过 (表型b,基因组a)=>(b表型b,基因组a)=> [(b,b)] - >双 - >双 - > (Something a,IO [b])


I'm trying to create a simple Haskell evolutionary algorithm and I'm trying to make it as general as possible. This was originally an assignment which I solved with Python at the time which I wanted to go back to when I had more time and solve in Haskell. The assignment needed the code to be very flexible and I have tried to recreate that in my preliminary Haskell implementation.

In the code below you can see the error GHC is giving me:

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

I have the following class declarations:

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

The code that is giving me the problem is:

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

I'm not entirely sure I understand the error and I would think that because both mom and dad are of class Phenotype which means they must support a genome method this should not be a problem. One problem I can see is that GHC can't make sure that the newly created Genomes will result in the same Phenotypes as it receives, but I'm not sure of how to solve that problem. There also might be some problems with the class declarations that I have overlooked so I would probably help to get someone better than me to look it over.

解决方案

children :: Genome a => [(a,a)]. ch1 :: Genome a => [a]. etc. "What data type is a?" - asks Haskell. "I need to check it belongs to the Genome type class".

Nothing in the code determines the concrete data type of a, you only operate with methods.

You need to put a into the return type too, and add Genome a into the constraint, so that it will be determined by a call site of breed:

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

这篇关于无法理解GHC对歧义的抱怨的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆