如何确定HVect的所有子维度?

时间:2016-04-09 21:08:09

标签: dependent-type idris

我想将HVect的所有子维度确定为HVect

示例:

import Data.HVect

myHVect : HVect [Int, String, List Nat]
myHVect = [42, "text", [1, 2, 3]]

subDimensions : HVect [ HVect [Int], HVect [Int, String], HVect [Int, String, List Nat] ]
subDimensions = subDimHVect myHVect
-- [ [42], [42, "text"], [42, "text", [1, 2, 3]] ]

我的方法如下:

subDimHVect v = subDimHVect' [] [] v
  where
    subDimHVect' result _ [] = result
    subDimHVect' result lastDim (x::xs) =
      let nextDim = lastDim ++ [x] in
      subDimHVect' (result ++ [nextDim]) nextDim xs

但我不知道如何正确输入subDimHVectsubDimHVect'。实施似乎很好:

手动计算示例:

subDimHVect [42, "text", [1, 2, 3]]
  = subDimHVect' [] [] [42, "text", [1, 2, 3]]
  = subDimHVect' [[42]] [42] ["text", [1, 2, 3]]
  = subDimHVect' [[42], [42, "text"]] [42, "text"] [[1, 2, 3]]
  = subDimHVect' [[42], [42, "text"], [42, "text", [1, 2, 3]]] [42, "text", [1, 2, 3]] []
  = [[42], [42, "text"], [42, "text", [1, 2, 3]]]

我对Idris和依赖类型都很陌生。我希望找到一些缺少类型签名的帮助。

修改 我找到了另一种可能更容易输入的方法,即使我无法计算出类型(definition of reverse):

subDimHVect v = reverse (subDimHVect' (reverse v))
  where
    subDimHVect' [] = []
    subDimHVect' (x::xs) = [(x::xs)] ++ (subDimHVect' xs)

手动计算示例(使用第二种方法):

subDimHVect [42, "text", [1, 2, 3]]
  = reverse (subDimHVect' (reverse [42, "text", [1, 2, 3]]))
  = reverse (subDimHVect' [[1, 2, 3], "text", 42])
  = reverse ([ [[1, 2, 3], "text", 42] ] ++ (subDimHVect' ["text", 42]))
  = reverse ([ [[1, 2, 3], "text", 42] ] ++ [ ["text", 42] ] ++ (subDimHVect' [42]))
  = reverse ([ [[1, 2, 3], "text", 42] ] ++ [ ["text", 42] ] ++ [ [42] ] ++ (subDimHVect' []))
  = reverse ([ [[1, 2, 3], "text", 42] ] ++ [ ["text", 42] ] ++ [ [42] ] ++ [])
  = reverse ([ [[1, 2, 3], "text", 42], ["text", 42], [42] ])
  = [ [42], [42, "text"], [42, "text", [1, 2, 3]] ]

1 个答案:

答案 0 :(得分:2)

首次尝试:

subDimensions : HVect ts -> HVect xs

xs将被视为隐式参数(如subDimensions : {ts : Vect n Type} -> {xs : Vect k Type} -> HVect ts -> HVect xs中所述),因此调用者可以说明结果HVect的外观如何。那不对。我们可以同时创建xs(如果您了解如何,请参阅此答案的历史记录):

subDimensions : HVect {k} ts -> (xs : (Vect k Type) ** HVect xs)

但是,

subDimensions : HVect ts -> HVect (dimType ts)

会更有用。在第二次尝试之后,我们可以创建

dimType : Vect k Type -> Vect k Type
dimType [] = []
dimType (x :: xs) = (HVect (vreverse (x::xs))) :: dimType xs

并遵循类型的结构,我们定义了助手subDimensions'

subDimensions' : HVect ts -> HVect (dimType ts)
subDimensions' [] = []
subDimensions' (x :: xs) = (hreverse (x :: xs)) :: subDimensions' xs

和包装器

subDimensions : HVect ts -> HVect (vreverse (dimType (vreverse ts)))
subDimensions xs = hreverse $ subDimensions' $ hreverse xs

(有关hreversevreverse的定义,请参阅here

相关问题