简体   繁体   English

多参数类型类上的“无法推断”错误

[英]"Could not deduce" error on multi-parameter type class

I have this code:我有这个代码:

{-# LANGUAGE MultiParamTypeClasses #-}
import System.Random (RandomGen(..))

class RandomGen gen => Shadow gen light where
    shadowRay :: gen -> light -> Float
    eval      :: light -> Float

and I get that error:我得到了那个错误:

 [1 of 1] Compiling Main ( problem.hs, problem.o ) problem.hs:6:5: error: * Could not deduce (Shadow gen0 light) from the context: Shadow gen light bound by the type signature for: eval :: Shadow gen light => light -> float -> float at problem.hs:6:5-40 The type variable `gen0' is ambiguous * In the ambiguity check for `eval' To defer the ambiguity check to use sites, enable AllowAmbiguousTypes When checking the class method: eval :: forall gen light. Shadow gen light => forall float. light -> float -> float In the class declaration for `Shadow'

This is problem from GHC 7.10+.这是 GHC 7.10+ 的问题。 Before it was working.在它工作之前。 There is a fix if I add "gen" parameter to "eval", like:如果我将“gen”参数添加到“eval”,则有一个修复,例如:

eval :: gen -> light -> Float

But I don't want to add a new value parameter which will not be used.但我不想添加一个不会使用的新值参数。 Is there some kind of other way for type resolution?有没有其他的类型解析方式?

The problem is that eval does not use gen , and so specialising its type is not enough to decide which gen to use when picking the Shadow instance to use.问题是eval不使用gen ,因此在选择要使用的Shadow实例时,专门化其类型不足以决定使用哪个gen One possible solution is using a functional dependency to enforce that there will be only one gen for each choice of light :一种可能的解决方案是使用函数依赖来强制每种light选择只有一个gen

{-# LANGUAGE FunctionalDependencies #-}

class RandomGen gen => Shadow gen light | light -> gen where
    shadowRay :: gen -> light -> Float
    eval      :: light -> Float

It is possible, however, that you don't want or need to couple light and gen in this manner.但是,您可能不想或不需要以这种方式耦合light gen In that case, you might want to consider the opposite alternative of removing gen from the type class -- if gen and light aren't related, you don't need a multi-parameter type class to relate them:在这种情况下,您可能需要考虑从类型类中删除gen的相反选择——如果genlight不相关,则不需要多参数类型类来关联它们:

class Shadow light where
    shadowRay :: RandomGen gen => gen -> light -> Float
    eval      :: light -> Float

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM