“无法推断".多参数类型类上的错误 [英] "Could not deduce" error on multi-parameter type class
问题描述
我有此代码:
{-# LANGUAGE MultiParamTypeClasses #-}
import System.Random (RandomGen(..))
class RandomGen gen => Shadow gen light where
shadowRay :: gen -> light -> Float
eval :: light -> Float
我得到那个错误:
[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'
这是GHC 7.10+中的问题.在工作之前.如果我将"gen"参数添加到"eval",则有一个解决方法,例如:
This is problem from GHC 7.10+. Before it was working. There is a fix if I add "gen" parameter to "eval", like:
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?
推荐答案
问题是eval
不使用gen
,因此仅对其类型进行专门化不足以决定在选择该类型时使用哪个gen
.要使用的Shadow
实例.一种可能的解决方案是使用功能依赖性,以强制每个light
选择只有一个gen
:
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. One possible solution is using a functional dependency to enforce that there will be only one gen
for each choice of light
:
{-# LANGUAGE FunctionalDependencies #-}
class RandomGen gen => Shadow gen light | light -> gen where
shadowRay :: gen -> light -> Float
eval :: light -> Float
但是,您可能不希望或不需要以这种方式耦合light
和gen
.在这种情况下,您可能要考虑从类型类中删除gen
的相反选择-如果gen
和light
不相关,则不需要多参数类型类来将它们相关:
It is possible, however, that you don't want or need to couple light
and gen
in this manner. 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:
class Shadow light where
shadowRay :: RandomGen gen => gen -> light -> Float
eval :: light -> Float
这篇关于“无法推断".多参数类型类上的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!