data N_ary = N_ary Int String Int deriving Eq
将数字存储到各种基础。例如,基数2,10和16的15分别是N_ary 1 "1111" 2
,N_ary 1 "15" 10
和N_ary 1 "F" 16
。 (第一个字段是-1,0或1作为符号。)
我定义了一个运算符infixl 5 ~>
,用于将事物转换为N_ary
个对象和一个可转换类型的类。
class N_aryAble a where
(~>) :: a -> Int -> N_ary
我对instance N_aryAble Integer
或instance 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 。还有更好的方法吗?
感谢。
答案 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