首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在haskell中使用GADT实现矩阵和向量

无法在haskell中使用GADT实现矩阵和向量
EN

Stack Overflow用户
提问于 2018-08-14 22:10:28
回答 1查看 89关注 0票数 0

我是Haskell的初学者。我试图在haskell中实现矩阵和向量。我希望它们支持Num类型类中的所有类型,但不支持其他类型,所以我尝试使用GADT,但我收到了错误。你能解释一下为什么我收到错误吗?或者我可以在没有这种方式的情况下获得相同的功能。

我的代码:

代码语言:javascript
复制
{-# LANGUAGE GADTs #-}

class LStruct s where
  scale :: (Num a) => a -> s -> s
  add :: s -> s -> s


data Vector a where
  Vector :: (Num a) => a -> Vector [a]

data Matrix a where
  Matrix :: (Num a) => a -> Matrix [a]


instance LStruct (Vector a) where
  scale a (Vector xs) = Vector (map (*a) xs)
  add (Vector xs) (Vector ys) = Vector (zipWith (+) xs ys)

错误:

代码语言:javascript
复制
[-Wdeferred-type-errors]
• Could not deduce: a2 ~ [a1]
  from the context: (a ~ [a2], Num a2)
    bound by a pattern with constructor:
               Vector :: forall a. Num a => a -> Vector [a],
             in an equation for ‘scale’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:12-20
  ‘a2’ is a rigid type variable bound by
    a pattern with constructor:
      Vector :: forall a. Num a => a -> Vector [a],
    in an equation for ‘scale’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:12-20
• In the second argument of ‘map’, namely ‘xs’
  In the first argument of ‘Vector’, namely ‘(map (* a) xs)’
  In the expression: Vector (map (* a) xs)
• Relevant bindings include
    xs :: a2
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:19)
    a :: a1
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:9)
    scale :: a1 -> Vector a -> Vector a
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:3)

[-Wdeferred-type-errors]
• Could not deduce: a2 ~ [c0]
  from the context: (a ~ [a1], Num a1)
    bound by a pattern with constructor:
               Vector :: forall a. Num a => a -> Vector [a],
             in an equation for ‘add’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:21:8-16
  or from: (a ~ [a2], Num a2)
    bound by a pattern with constructor:
               Vector :: forall a. Num a => a -> Vector [a],
             in an equation for ‘add’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-       TEMP.hs:21:20-28
  ‘a2’ is a rigid type variable bound by
    a pattern with constructor:
      Vector :: forall a. Num a => a -> Vector [a],
    in an equation for ‘add’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:21:20-28
  Expected type: [c0]
    Actual type: a1
• In the second argument of ‘zipWith’, namely ‘xs’
  In the first argument of ‘Vector’, namely ‘(zipWith (+) xs ys)’
  In the expression: Vector (zipWith (+) xs ys)
• Relevant bindings include
    ys :: a2
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:21:27)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-14 22:20:33

我想你打算写:

代码语言:javascript
复制
data Vector a where
    Vector :: (Num a) => [a] -> Vector a

“向量或a可以从a的列表中构造”

您的问题中的版本采用单个a,并且您得到的错误是关于GHC试图映射到该单个值。

更广泛地说,我建议将Num约束从构造函数移动到使用Vector的实例和函数。以这种方式编写的代码似乎可以从GHC获得更好的错误消息,并且更容易使用。我不确定这是不是有深层次的原因,或者只是GHC开发人员把时间花在哪里的问题。

因此,实例声明可能会变成:

代码语言:javascript
复制
instance Num a => LStruct (Vector a) where

并且实例主体可以保持不变。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51843493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档