如何告诉GHC来自整体应该做什么

时间:2016-11-23 16:00:24

标签: haskell

data N_ary = N_ary Int String Int deriving Eq

将数字存储到各种基础。例如,基数2,10和16的15分别是N_ary 1 "1111" 2N_ary 1 "15" 10N_ary 1 "F" 16。 (第一个字段是-1,0或1作为符号。)

我定义了一个运算符infixl 5 ~>,用于将事物转换为N_ary个对象和一个可转换类型的类。

class N_aryAble a where
  (~>) :: a -> Int -> N_ary

我对instance N_aryAble Integerinstance N_aryAble N_ary(将一个基地更改为另一个基地)没有任何问题,但我遇到了问题

instance N_aryAble Int where
  int ~> base = fromIntegral int ~> base

Ambiguous type variable ‘a0’ arising from a use of ‘fromIntegral’
prevents the constraint ‘(Num a0)’ from being solved.
...

Ambiguous type variable ‘a0’ arising from a use of ‘~>’
prevents the constraint ‘(N_aryAble a0)’ from being solved.
...

如果没有特殊设置,则不允许在实例声明中键入签名。

instance N_aryAble Int where
  (~>) :: Int -> Int -> N_ary
  int ~> base = fromIntegral int ~> base

 Illegal type signature in instance declaration:
    (~>) :: Int -> Int -> N_ary
  (Use InstanceSigs to allow this)

以下作品。

instance N_aryAble Int where
  int ~> base = fromIntegral int + (0::Integer) ~> base

> (5::Int) ~> 2  ==> N_ary 1 "101" 2

但这看起来很丑陋而且 ad hoc 。还有更好的方法吗?

感谢。

2 个答案:

答案 0 :(得分:3)

您可以为fromIntegral调用提供类型注释,以使其不含糊。

instance N_aryAble Int where
  int ~> base = (fromIntegral int :: Integer) ~> base

答案 1 :(得分:3)

问题不在于编译器无法推断 来转换类型。这可以通过特定实例方法的签名来修复,BTW可以像

那样编写
instance N_aryAble Int where
  (~>) = (~~>)
   where (~~>) :: Int -> Int -> N_ary
         int ~~> base = fromIntegral int ~> base

但是这个信息已经从类方法签名中清楚了,所以它对你没有帮助。

不,问题是您没有指定转换为 的类型,并且因为~>的参数再次是多态的,编译器具有没有其他可以推断它。这也可以将Int转换为Int,从而导致无限递归循环,因为您最终会尝试定义相同的~>实例化!

您可以使用fromIntegral作为shown by chi的结果签名来澄清这一点,或者您可以简单地使用to-版本的转换函数,该函数与{{Integer单态化1}}结果:

instance N_aryAble Int where
  int ~> base = toInteger int ~> base