カスタム型クラスのインスタンス化:期待される型「b」を実際の型「Int」と一致させることができませんでした

オレイアード

私は現在、任意のカスタムタイプをに変換できるタイプクラスを実装しようとしていますIntegral(これらのタイプはすべてインデックスまたはウェイトに変換可能である必要があります)。この特定のケースでは、特定のオクターブの音符をピアノの鍵盤キーのインデックスに変換できることを確認するために使用したいと思います。

import Data.Int

class Convertible a where
  toIntegral :: Integral b => a -> b

data Note = Note Tone Int

instance Convertible Note where
    toIntegral (Note t o) = o * 12 + toIntegral t

しかし、コンパイラは、toIntegralforの実装がNote私の型Convertibleクラスに準拠していないと文句を言います。

    • Couldn't match expected type ‘b’ with actual type ‘Int’
  ‘b’ is a rigid type variable bound by
    the type signature for:
      num :: forall b. Integral b => Note -> b
    at src/Note.hs:11:5
• In the expression: octave * 12 + (num tone)
  In an equation for ‘num’:
      num (Note tone octave) = octave * 12 + (num tone)
  In the instance declaration for ‘Convertible Note’
• Relevant bindings include
    num :: Note -> b (bound at src/Note.hs:11:5)

私が理解している限り、toIntegral関数a -> Intをに制約した場合関数の内容はに評価されると見なされますIntegral => b -> a -> bクラスをInt実装しているので、何が悪いのかわかりませんIntegralよね?

私がここで明らかに間違っていることを理解するのを手伝ってくれませんか?

支出

型変数は、呼び出し先ではなく、呼び出し元によって選択されます。あなたの場合、toIntegral選択することはできませんb、その発信者は選択しますそのタイプに応じて、これらの使用法はすべてタイプチェックする必要があります

toIntegral (Note t o) :: Int
toIntegral (Note t o) :: Integer
toIntegral (Note t o) :: Word32
-- etc.

解決策は、変換することであるIntのと同様、すなわち改宗oので、任意の整数を返すために、bとだけではなくInt

たとえば、任意のタイプにfromIntegral o変換できるためo、任意のNumタイプに変換できますIntegral

とにかく、あなたは本当にあなたのためにそのタイプが必要toIntegralですか?

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ