Haskell: аргумент без переменной типа в ограничении?

Это код, он немного непростой, прошу прощения. В основном функция 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))

Я пробовал использовать такие гибкие контексты,

: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

Как я могу это исправить?

Обратите внимание на разницу между кортежами и различными типами Vector.

Carl 22.10.2018 04:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
451
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно использовать конструктор 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,) в качестве битов более высокого порядка.

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

leftaroundabout 22.10.2018 11:36

Другие вопросы по теме