2016-11-23 6 views
0
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である。インテグラルから何をすべきかGHCに伝える方法

オブジェクトをN_aryオブジェクトに変換するための演算子infixl 5 ~>と、変換可能な型のクラスを定義しました。

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 

しかし、それは醜いようだとアドホック。より良い方法がありますか?

ありがとうございました。

答えて

3

fromIntegralコールに型名を付けることができます。そのため、あいまいではありません。

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

感謝を。それを考えなかった。 – RussAbbott

+0

'TypeApplications'に言及する価値がありますか? – Alec

+0

@Alecはい、それは実際に私の最初の選択です。しかし、そのような単純なケースでは、タイプ注釈で十分であり、拡張を必要としない。さらに、ここでは、 'fromIntegral @ _ @ Integer int'が必要です。これは、第2の型の引数を明示する必要があるため、便利ではありません。 – chi

3

問題は、コンパイラからタイプを変換するからを推測することができないということではありません。それはところであなたは

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

のように書くことができます。しかし、その情報は、クラスメソッドのシグネチャからすでに明らかであるので、それはあなたを助けにはなりませんその特定のインスタンスメソッドのための署名で固定することができます。

はありません、問題はあなたがを変換するために、どのようなタイプ指定していないということです、そして~>への引数が再び多型であるため、コンパイラはからそれを推測する他には何もありません。これはIntIntに変換することができ、定義しようとしている同じ~>インスタンシエーションで終了するため、無限ループが発生します。

あなたはshown by chiとしてfromIntegralの結果に署名し、これを明確にすることができますか、あなたは、単にInteger結果に単形だ変換関数のto- -version使用することができます。

instance N_aryAble Int where 
    int ~> base = toInteger int ~> base 
関連する問題