"无法演绎"多参数类型类的错误

时间:2017-01-11 13:57:15

标签: haskell ghc typeclass

我有这段代码:

{-# 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

但我不想添加一个不会被使用的新值参数。是否有其他类型的解决方法?

1 个答案:

答案 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

但是,您可能不希望或需要以这种方式结合lightgen。在这种情况下,您可能需要考虑从类型类中删除gen的相反方法 - 如果genlight没有关系,则不要需要一个多参数类型类来关联它们:

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