Я не могу найти в Хаскеле, чтобы указать тип вызова ' neg ':
instance Arith (V3 e) where neg x = vfmap (neg :: e->e) x
(V3 e) и e являются экземплярами Arith . Здесь я хочу вызвать ' neg ', уже определенный для типа 'e' . Но для этого требуется явный тип в вызове ' neg ', и никакое выражение не может разрешить тип? Если использовать конкретный экземпляр 'e' , это нормально.
vfmap (neg :: Dist->Dist ) x
- это работает (но не достаточно широко)
vfmap (neg :: e->e) x
- Нет экземпляра для ( Arith e1 ), возникшего в результате использования ‘neg ’
vfmap neg e
- Неоднозначная переменная типа "e0", возникающая в результате использования "neg"
предотвращает ограничение ‘(Arith e0)’.
vfmap (neg :: Arith e => e->e) x
- то же самое
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, InstanceSigs #-}
data Dist = Inch Float deriving (Show)
class Arith a where
neg :: a->a
instance Arith Dist where
neg (Inch x) = Inch (-x)
data V2 e = V2 e e deriving (Show)
data V3 e = V3 e e e deriving (Show)
class VMap c e where
vfmap :: (e->e)->c->c
instance VMap (V2 e) e where
vfmap f (V2 x1 x2) = V2 (f x1) (f x2)
instance VMap (V3 e) e where
vfmap f (V3 x1 x2 x3) = V3 (f x1) (f x2) (f x3)
-- 2 & 3 point vectors should also be Arith
instance Arith (V2 Dist) where
neg x = vfmap (neg :: Dist->Dist) x -- works, but must have type on neg
instance Arith (V3 e) where
neg x = vfmap (neg :: Arith e => e->e) x -- nothing here seems to work
vfmap может применяться к ( V2 e ) или a ( V3 e ), любому типу вектора для вектора любого Arith тип элемента.
Это не скомпилируется, если тип элемента является переменной типа, например,
• Неопределенная переменная типа type e0 ’, возникающая из сигнатуры типа выражения
предотвращает ограничение ‘ (Arith e0) ’.
Возможное исправление: используйте аннотацию типа, чтобы указать, каким должно быть 10 e0 ’.