Haskell: аргумент без переменной типа в ограничении? - PullRequest
0 голосов
/ 22 октября 2018

Это код, он немного не простой, я прошу прощения.По сути, функция vecF должна иметь два результата v1, v2 при вводе двух входов v0 и vs, но по какой-то причине я получаю сообщения об ошибках.

newtype Vector2 a = Vector2 (a,a)
  deriving (Show,Eq)
newtype Vector3 a = Vector3 (a,a,a)
  deriving (Show,Eq)
newtype Vector4 a = Vector4 (a,a,a,a)
  deriving (Show,Eq)

class VectorSpace v where
  vecZero       :: (Num a) => v a
  vecSum        :: (Num a) => v a -> v a -> v a
  vecScalarProd :: (Num a) => a -> v a -> v a
  vecMagnitude  :: (Floating a) => v a -> a
  vecInnerProd  :: (Num a) => v a -> v a-> a

instance VectorSpace Vector2 where
  vecZero = Vector2 (0,0)
  vecSum (Vector2 (q,w)) (Vector2 (a,s)) = Vector2 (q+a,w+s)
  vecScalarProd x (Vector2 (q,w)) = Vector2 (q*x,w*x)
  vecMagnitude (Vector2 (q,w)) = sqrt(q*q+w*w)
  vecInnerProd (Vector2 (q,w)) (Vector2 (a,s)) = q*a+w*s

instance VectorSpace Vector3 where
  vecZero = Vector3 (0,0,0)
  vecSum (Vector3 (q,w,e)) (Vector3 (a,s,d)) = Vector3 (q+a,w+s,e+d)
  vecScalarProd x (Vector3 (q,w,e)) = Vector3 (q*x,w*x,e*x)
  vecMagnitude (Vector3 (q,w,e)) = sqrt(q*q+w*w+e*e)
  vecInnerProd (Vector3 (q,w,e)) (Vector3 (a,s,d)) = q*a+w*s+e*d

instance VectorSpace Vector4 where
  vecZero = Vector4 (0,0,0,0)
  vecSum (Vector4 (q,w,e,r)) (Vector4 (a,s,d,f)) = Vector4 
(q+a,w+s,e+d,r+f)
  vecScalarProd x (Vector4 (q,w,e,r)) = Vector4 (q*x,w*x,e*x,r*x)
  vecMagnitude (Vector4 (q,w,e,r)) = sqrt(q*q+w*w+e*e+r*r)
  vecInnerProd (Vector4 (q,w,e,r))(Vector4 (a,s,d,f)) =
    q*a+w*s+e*d+r*f

vecF :: (Floating a, Ord a, VectorSpace v) => v a -> [v a] -> (v a, v a)
vecF v0 vs = (v1,v2) where
            v0Neg     = vecScalarProd (-1) v0
            v1MinMag  = minimumBy (comparing snd)(zip [0..]  
[vecMagnitude (vecSum v0Neg v) | v <- vs])
            v1Index   = fst v1MinMag
            v1Min     = [vecSum v0Neg v | v <- vs] !! v1Index
            v1        = vecSum v0 v1Min

            v2MaxMag  = maximumBy (comparing snd)(zip [0..]  
[vecMagnitude (vecSum v0Neg v) | v <- vs])
            v2Index   = fst v2MaxMag
            v2Max     = [vecSum v0Neg v | v <- vs] !! v2Index
            v2        = vecSum v0 v2Max

Ниже приведены ошибки, которые я получил, когда ввожу:

 vecF (1,2,3,3) [(2,1,2,2),(13,3,2,1)]

.

 •Non type-variable argument
    in the constraint: VectorSpace ((,,,) t2 t1 t)
  (Use FlexibleContexts to permit this)
  •When checking the inferred type
    it :: forall a t t1 t2.
          (Num t, Num t1, Num t2, VectorSpace ((,,,) t2 t1 t), Ord a,
           Floating a) =>
          ((t2, t1, t, a), (t2, t1, t, a))

Я пытался использовать FlexibleContexts, как это,

:set -XFlexibleContexts

, а затем я получаю это новое сообщение об ошибке

 • When checking the inferred type
    it :: forall a t t1 t2.
          (Num t, Num t1, Num t2, VectorSpace ((,,,) t2 t1 t), Ord a,
           Floating a) =>
          ((t2, t1, t, a), (t2, t1, t, a))
• No instance for (VectorSpace ((,,,) t2 t1 t0))
    arising from a use of ‘it’
• In a stmt of an interactive GHCi command: print it

Можно ли как-нибудь это исправить?

1 Ответ

0 голосов
/ 22 октября 2018

Вам необходимо использовать конструктор Vector4, а именно

vecF (Vector4 (1,2,3,3)) [ Vector4 (2,1,2,2), Vector4 (13,3,2,1)]

По сути, сообщение об ошибке говорит вам именно то, что вам нужно знать, а именно, что (1,2,3,3) не имеет VectorSpaceпример.В данном случае это происходит потому, что вы вызываете его для чего-то, что не является вектором для его базового типа.

Причина, по которой он говорит, что нет экземпляра для VectorSpace ((,,,) t2 t1 t), заключается в том, что он пытается соответствовать типу (1, 2, 3, 4) с v a более чем a - и здесь он попытался использовать Num t, Num t1, Num t2 => (t, t1, t2,) в качестве старшего бита.

...