【发布时间】:2019-04-15 05:55:31
【问题描述】:
我在 Haskell 中无论如何都找不到指定调用 'neg' 的类型:
instance Arith (V3 e) where neg x = vfmap (neg :: e->e) x
(V3 e) 和 e 都是 Arith 的实例。这里我想调用已经为类型'e'定义的'neg'。但这需要 'neg' 调用上的显式类型,并且没有表达式可以解析该类型?如果使用 'e' 的特定实例,那就没问题了。
vfmap (neg :: Dist->Dist ) x -- 这行得通(但不够通用)
vfmap (neg :: e->e) x -- (Arith e1) 没有因使用 ‘neg’ 而产生的实例
vfmap neg e -- 由使用“neg”引起的模棱两可的类型变量“e0”
防止约束“(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) 或 (V3 e),任何一种向量类型都可以用于任何 Arith 元素类型。
当元素类型是类型变量时,这似乎无法编译,例如
• 由表达式类型签名产生的不明确类型变量“e0” 防止约束“(Arith e0)”被解决。 可能的解决方法:使用类型注释来指定“e0”应该是什么。
【问题讨论】: