0

私は、Vector ライブラリを作成することによって、Haskell の型システムのより細かい部分を理解しようとしています。理想的には、C++ のように機能するオーバーロードされたベクトル乗算操作が必要です。つまり、任意のサイズのベクトルをスカラーで任意の順序で乗算できます。これを行うために、複数のパラメーター型クラスと型ファミリ拡張を組み合わせようとしました。

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances #-}

data Vec2 a = Vec2 (a,a) deriving (Show, Eq, Read)

class Vector a where
    (<+>) :: a -> a -> a

class VectorMul a b where
    type Result a b
    (<*>) :: a -> b -> Result a b

instance (Num a) => Vector (Vec2 a) where
    Vec2 (x1,y1) <+> Vec2 (x2,y2) = Vec2 (x1+x2, y1+y2)

instance (Num a) => VectorMul (Vec2 a) a where
    type Result (Vec2 a) a = (Vec2 a)
    Vec2 (x,y) <*> a = Vec2 (x*a, y*a)

works :: (Num a) => Vec2 a -> a -> Vec2 a
works a b = a <*> b

このコードは、少なくとも関数のように使用されている場合は機能しているようworksです。Vec2 (3,4) <*> 5しかし、 GHCi のような単純な式を入力しようとすると、(Num xx)型変数があいまいであると報告されます。これは私には奇妙です...この場合、何が欠けていますか? Haskell は、リテラルに対して同じ任意の型を選択して、型式を機能させることができる必要があります (works関数で行うように)。

4

1 に答える 1