Haskell:约束中是否存在非类型变量参数?

时间:2018-10-22 02:48:23

标签: haskell types error-handling compiler-errors

这是代码,对不起,这有点不简单。基本上,如果输入两个输入v0和vs,则函数vecF应该具有两个结果v1,v2,但是由于某种原因,我最终收到错误消息。

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 :(得分:3)

您需要使用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,)作为较高种类的位。