简体   繁体   English

如何告诉GHC fromIntegral应该做什么

[英]How to tell GHC what fromIntegral should do

data N_ary = N_ary Int String Int deriving Eq

stores numbers to various bases. 将数字存储到各种基础。 For example 15 to the bases 2, 10, and 16 are N_ary 1 "1111" 2 , N_ary 1 "15" 10 , and N_ary 1 "F" 16 respectively. 例如,到基数N_ary 1 "1111" 2和16的15分别是N_ary 1 "1111" 2N_ary 1 "15" 10N_ary 1 "F" 16 (The first field is -1, 0, or 1 as a sign.) (第一个字段是-1、0或1作为符号。)

I defined an operator infixl 5 ~> for converting things into N_ary objects and a class for convertible types. 我定义了一个用于将事物转换为N_ary对象的运算符infixl 5 ~>和一个用于可转换类型的类。

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

I had no problems with instance N_aryAble Integer or instance N_aryAble N_ary (to change one base to another), but I ran into a problem with 我对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.
...

Type signatures within instance declarations are not allowed without a special setting. 如果没有特殊设置,则不允许实例声明中的类型签名。

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)

The following works. 以下作品。

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

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

But that seems ugly and ad hoc . 但这似乎是丑陋且临时的 Is there a better way? 有没有更好的办法?

Thanks. 谢谢。

You can provide a type annotation to the fromIntegral call, so to make it non ambiguous. 您可以为fromIntegral调用提供类型注释,以使其不模糊。

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

The problem is not that the compiler can't deduce what from to convert the type from. 问题不在于编译器无法推断出from转换为from的类型。 That could be fixed with a signature for that particular instance method, which BTW you could write like 可以使用该特定实例方法的签名来解决,顺便说一句,您可以这样写

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

But that information is already clear from the class method signature, so it won't help you. 但是该信息已经从类方法签名中清除了,因此对您没有帮助。

No, the problem is that you don't specify what type to convert to , and because the argument to ~> is again polymorphic the compiler has nothing else to infer it from. 不,问题在于您没有指定要转换哪种类型,并且由于~>的参数再次是多态的,因此编译器没有其他可推断出的类型。 This could as well convert Int to Int , causing an infinite recursion loop because you end up with the same ~> instantiation you're trying to define! 这也可能将Int转换为Int ,从而导致无限递归循环,因为最终您将尝试定义相同的~>实例!

You can either clarify this with a signature to the result of fromIntegral as shown by chi , or you can simply use the to- -version of the conversion function that's monomorphic with an Integer result: 您可以使用chi所示fromIntegral结果的签名来阐明这一点,也可以简单地将单态转换函数与Integer结果一起使用to- version:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM