繁体   English   中英

GADT评估程序的返回类型

[英]return type of GADT evaluator

我对为什么以下prodV中的最后一个模式不起作用感到有些困惑:

 {-# LANGUAGE GADTs #-}

data V a where
  V0 :: Float -> V Float
  Vn :: [Float] -> V [Float]

prodV :: (Num a) => V a -> V a -> a
prodV (V0 x) (V0 y) =  x * y
-- prodV (Vn x) (Vn y) = zipWith (*) x y -- this one works
prodV (Vn xs) (Vn ys) = [ sum $ zipWith (*) xs ys ]
prodV (V0 n) (Vn ys) = map (* n) ys 

GHCi 7.8.3抱怨:

Couldn't match type ‘Float’ with ‘[Float]’ 
Inaccessible code in
  a pattern with constructor
    Vn :: [Float] -> V [Float],
  in an equation for ‘prodV’
In the pattern: Vn ys`

有指针吗? 提前致谢

好吧,GHC会告诉您确切的问题所在。 根据您的定义, V0 something始终为V Float类型( something应为Float类型-但这与此处无关),而Vn anything始终为V [Float]类型。 但是prodV的类型签名指定两者都具有相同的V a 因此,在这种情况下, a应该同时为Float[Float] ,这是不可能的。

签名

prodV :: (Num a) => V a -> V a -> a

强制两个参数具有相同的类型参数,但是如果在V0Vn上匹配,则参数将必须具有类型参数不匹配的类型V FloatV [Float]

我不太确定您想要的语义是什么,但是我猜您想将GADT定义为类似

data V n where
  V0 :: n -> V n
  Vn :: [n] -> V n

和你的功能

prodV :: (Num a) => V a -> V a -> V a
prodV (V0 x) (V0 y) =  V0 $ x * y
prodV (Vn xs) (Vn ys) = Vn $ zipWith (*) xs ys
prodV (V0 n) (Vn ys) = Vn $ map (* n) ys

或可能

prodV' :: (Num a) => V a -> V a -> a
prodV' (V0 x) (V0 y) =  x * y
prodV' (Vn xs) (Vn ys) = sum $ zipWith (*) xs ys
prodV' (V0 n) (Vn ys) = sum $ map (* n) ys

您能描述一下您希望函数prodV实际执行的操作吗? 原始代码中的类型对我来说真的没有意义。

我只是想了解如何重载函数以模仿代数速记,但我想这不是正确的途径。 Haskell的惯用方式是什么? 例如,来自Numeric.Matrix

adaptScalar f1 f2 f3 x y
    | dim x == 1 = f1   (x@>0) y
    | dim y == 1 = f3 x (y@>0)
    | otherwise = f2 x y

instance Num (Vector Float) where
    (+) = adaptScalar addConstant add (flip addConstant)
    negate = scale (-1)
    (*) = adaptScalar scale mul (flip scale)
    signum = vectorMapF Sign
    abs = vectorMapF Abs
    fromInteger = fromList . return . fromInteger

根据操作数的维数选择运算符的正确实现(例如+或*)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM