如何在Edward Kmett的"线性"库中使用可变大小的向量?

Chr*_*ard 6 haskell vector linear-algebra ghc haskell-linear

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

最小代码:

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
Run Code Online (Sandbox Code Playgroud)

它给出了我不理解的这些错误:

• 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
Run Code Online (Sandbox Code Playgroud)

Ale*_*lec 5

因为Haskell不依赖于类型,所以它不能将类型级别提升到它可能仅在运行时获得的列表的长度.话n虽如此,你的目的是你可以创建多边形的代码,这些代码的大小超过了向量的大小(例如,你可以确保你没有采用具有不同长度的向量的点积).但是,如果要使用该信息,仍需要在编译时明确指定实际向量的长度.

什么linear 给你的是fromVector这在运行时进行检查,您提供给向量指定的类型相匹配.例如,

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)
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

... annnnd是的 - 我认为最后的互动是一个错误(除非有人能看到我错过的东西).该Trace (V 5)变体应该是可满足的,Dim n => Trace (V n)但由于某种原因它不是.

编辑

正如@ user2407038指出的那样,问题在于Dim n => Trace (V n)我上面提到的并不是多边形的 - 它只适用于n :: *我们希望它适用于任何类型(特别是n :: Nat在这种情况下).这种限制没有任何理由,因此我们可以继续定义我们自己的实例版本

ghci> :set -XPolyKinds
ghci> instance Dim n => Trace (V n)
ghci> trace m
106.0
Run Code Online (Sandbox Code Playgroud)

我打开了一个问题.

编辑2

现在问题已解决.我估计它应该可以进入下一个版本linear.


作为旁注,我使用-XDataKinds这样我可以写类型级文字(它们有类型GHC.TypeLits.Nat- 它们是特殊的并且硬连线到GHC中)-XOverloadedLists所以我可以写[1..5] :: Vector Int.

  • `Trace(V 5)`不满意因为种类错误,实例实际上是'Dim*n => Trace(V*n)`但是你需要`Dim Nat n => Trace(V Nat n) `或更一般地说'Dim kn => Trace(V kn)`.大概这只是一个错误,但你仍然可以自己声明适当的实例作为快速修复. (2认同)