私は現在、任意のカスタムタイプをに変換できるタイプクラスを実装しようとしています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
しかし、コンパイラは、toIntegral
forの実装が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]
コメントを追加