Haskell中数值文字与约束函数参数的不同行为

时间:2013-08-18 02:10:19

标签: haskell type-families

我一直试图通过编写一个Vector库来弄清楚Haskell类型系统中更多的一些。理想情况下,我想要一个有点像C ++的重载向量乘法运算,即,您可以按任意顺序将任意大小的向量乘以标量。 我试图结合多个参数类型类和类型族扩展来执行此操作:

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances #-}

data Vec2 a = Vec2 (a,a) deriving (Show, Eq, Read)

class Vector a where
    (<+>) :: a -> a -> a

class VectorMul a b where
    type Result a b
    (<*>) :: a -> b -> Result a b

instance (Num a) => Vector (Vec2 a) where
    Vec2 (x1,y1) <+> Vec2 (x2,y2) = Vec2 (x1+x2, y1+y2)

instance (Num a) => VectorMul (Vec2 a) a where
    type Result (Vec2 a) a = (Vec2 a)
    Vec2 (x,y) <*> a = Vec2 (x*a, y*a)

works :: (Num a) => Vec2 a -> a -> Vec2 a
works a b = a <*> b

此代码似乎有效,至少在函数works中使用时。但是当我尝试在GHCi中键入一个像Vec2 (3,4) <*> 5这样的简单表达式时,它会报告(Num xx)类型变量是不明确的。这对我来说很奇怪......在这种情况下我错过了什么? Haskell应该能够为文字选择相同的任意类型,以使类型表达式起作用(就像在works函数中一样)。

1 个答案:

答案 0 :(得分:1)

尝试写

Vec2 (3,4 :: Int) <*> (5 :: Int)

Vec2 (3,4) <*> 5 3,4 ::Num a并不保证5 :: Num ba具有相同的b和{{1}}