我有这段代码:
{-# 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",如:
eval :: gen -> light -> Float
但我不想添加一个不会被使用的新值参数。是否有其他类型的解决方法?
答案 0 :(得分:1)
问题是eval
没有使用gen
,因此专门设置其类型并不足以决定在选择gen
实例时要使用哪个Shadow
。一种可能的解决方案是使用functional dependency来强制每个gen
选项只有一个light
:
{-# LANGUAGE FunctionalDependencies #-}
class RandomGen gen => Shadow gen light | light -> gen where
shadowRay :: gen -> light -> Float
eval :: light -> Float
但是,您可能不希望或需要以这种方式结合light
和gen
。在这种情况下,您可能需要考虑从类型类中删除gen
的相反方法 - 如果gen
和light
没有关系,则不要需要一个多参数类型类来关联它们:
class Shadow light where
shadowRay :: RandomGen gen => gen -> light -> Float
eval :: light -> Float