首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Edward的“线性”库中使用可变大小的向量?

如何在Edward的“线性”库中使用可变大小的向量?
EN

Stack Overflow用户
提问于 2017-02-15 00:53:03
回答 1查看 309关注 0票数 7

我正在尝试使用ekmett的线性库,在Linear.V中,我遇到了一些可变长度向量的问题。我如何使用dim函数来获得向量的大小?如何在由嵌套的trace s构成的大方阵上使用V?我在这两种情况下都有错误。

最低代码:

代码语言:javascript
复制
import qualified Data.Vector as Vector
import Linear.V (V(V), dim)
import Linear.Vector (outer)
import Linear.Matrix (trace)

v, w :: V n Double -- What do I do here?
v = V $ Vector.fromList [1..5]
w = V $ Vector.fromList [2, 3, 5, 7, 11]

d = dim v
m = outer v w
t = trace m

它给出了这些我不明白的错误:

代码语言:javascript
复制
• Ambiguous type variable ‘n0’ arising from a use of ‘dim’
  prevents the constraint ‘(Linear.V.Dim n0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘n0’ should be.
  These potential instances exist:
    two instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the expression: dim v
  In an equation for ‘d’: d = dim v

• Ambiguous type variable ‘n1’ arising from a use of ‘trace’
  prevents the constraint ‘(Linear.V.Dim n1)’ from being solved.
  Probable fix: use a type annotation to specify what ‘n1’ should be.
  These potential instances exist:
    two instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the expression: trace m
  In an equation for ‘t’: t = trace m
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-15 02:10:26

因为Haskell不是依赖类型的,所以它不能将它可能在运行时获得的列表的长度提升到类型级别。尽管如此,n的目的是,您可以使代码对向量的大小具有多态性(例如,您可以确保不使用长度不同的向量的点积)。但是--如果要使用这些信息,仍然需要在编译时显式地指定实际向量的长度。

linear提供给您的是fromVector,它在运行时执行一次检查,检查您给出的向量是否与您指定的类型匹配。例如,

代码语言:javascript
复制
ghci> :set +t -XDataKinds -XOverloadedLists
ghci> import Linear
ghci> import Linear.V
ghci> fromVector [1,2,3] :: Maybe (V 3 Int)
Just (V {toVector = [1,2,3]})
it :: Maybe (V 3 Int)
ghci> fromVector [1,2,3] :: Maybe (V 2 Int)
Nothing
it :: Maybe (V 3 Int)

因此,在您的情况下,您可能应该执行如下操作:

代码语言:javascript
复制
ghci> Just v = fromVector [1..5]           :: Maybe (V 5 Double)
v :: V 5 Double
ghci> Just w = fromVector [2, 3, 5, 7, 11] :: Maybe (V 5 Double)
w :: V 5 Double
ghci> dim v
5
it :: Int
ghci> m = outer v w
m :: V 5 (V 5 Double)
ghci> trace m
<interactive>:44:1: error:
   • No instance for (Trace (V 5)) arising from a use of ‘trace’
   • In the expression: trace m
     In an equation for ‘it’: it = trace m

...annnnd是的-我认为最后的交互是一个bug (除非有人能看到我缺少的东西)。Trace (V 5)变体在Dim n => Trace (V n)实例中应该是可以满足的,但由于某些原因,它不能满足。

编辑

正如@user2407038所指出的,问题是上面提到的Dim n => Trace (V n)不是多义的--它只适用于n :: *,而我们希望它适用于任何类型(特别是本例中的n :: Nat )。这个限制并没有任何理由,所以我们可以继续定义我们自己的实例版本。

代码语言:javascript
复制
ghci> :set -XPolyKinds
ghci> instance Dim n => Trace (V n)
ghci> trace m
106.0

我开了一个问题

编辑2

这个问题现在已经解决了。我认为它可能会进入linear的下一个版本。

另外,我使用-XDataKinds,这样我就可以编写类型级别的文字(它们有类GHC.TypeLits.Nat -它们是特殊的,并且硬连接到GHC中)和-XOverloadedLists,这样我就可以编写[1..5] :: Vector Int了。

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

https://stackoverflow.com/questions/42238952

复制
相关文章

相似问题

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