vector - Idris - 自定义相关数据类型的映射函数失败

标签 vector tuples idris dependent-type map-function

我对 idris 和依赖类型相对较新,遇到了以下问题 - 我创建了一个类似于向量的自定义数据类型:

infixr 1 :::

data TupleVect : Nat -> Nat -> Type -> Type where
    Empty : TupleVect Z Z a
    (:::) : (Vect o a, Vect p a) ->
            TupleVect n m a ->
            TupleVect (n+o) (m+p) a

exampleTupleVect : TupleVect 5 4 Int
exampleTupleVect = ([1,2], [1]) ::: ([3,4],[2,3]) ::: ([5], [4]) ::: Empty

它是通过添加向量元组来归纳构造的,并通过每个元组位置的向量长度之和进行索引。

我尝试为我的数据类型实现映射函数:

tupleVectMap : ((Vect k a, Vect l a) -> (Vect k b, Vect l b)) ->
               TupleVect n m a -> TupleVect n m b
tupleVectMap f Empty = Empty
tupleVectMap f (x ::: xs) = let fail = f x
                            in ?rest_of_definition

这会产生以下类型错误:

   |
20 | tupleVectMap f (x ::: xs) = let fail = f x
   |                             ~~~~~~~~~~~~~~ ...
When checking right hand side of tupleVectMap with expected type
        TupleVect (n + o) (m + p) b

Type mismatch between
        (Vect o a, Vect p a)
and
        (Vect k a, Vect l a)

类型检查器似乎无法统一向量的长度 在提取的元组 x 中以及 f 的参数中所需的长度。然而我不 理解为什么会这样,因为 k 和 l 只是类型名称,表明 f 不会改变给定向量的长度。

由于以下类型检查,我更加困惑:

tupleVectMap' : TupleVect n m a -> TupleVect n m b
tupleVectMap' Empty = Empty
tupleVectMap' (x ::: xs) =
    let nonfail = f x
    in ?rest_of_definition
      where
        f : ((Vect k a, Vect l a) -> (Vect k b, Vect l b))

这里 f 具有完全相同的类型签名。唯一的区别是 f 是 本地定义。

最佳答案

如果您:set showimplicits在引用中您将看到这两个函数之间的差异。

tupleVectMap

f : (Data.Vect.Vect k a, Data.Vect.Vect l a) ->
    (Data.Vect.Vect k b, Data.Vect.Vect l b)
x : (Data.Vect.Vect o a, Data.Vect.Vect p a)

因为ko ( lp )不一定相等, x不能应用于f 。基本上,如果您调用tupleVectMap ,您已经确定 f只接受Vect长度k .

tupleVectMap'期间这是

f : {k : Prelude.Nat.Nat} -> {l : Prelude.Nat.Nat} ->
    (Data.Vect.Vect k a, Data.Vect.Vect l a) ->
    (Data.Vect.Vect k b, Data.Vect.Vect l b)
x : (Data.Vect.Vect o a, Data.Vect.Vect p a)

这里f使用两个隐式参数来设置 Vect 的长度每当它被调用时。所以f x {k=o} {l=p}有效(尽管您不必指定隐式参数)。

如果您将函数类型定义为

,它也会起作用
tupleVectMap : ({k, l : Nat} -> (Vect k a, Vect l a) -> (Vect k b, Vect l b)) ->
               TupleVect n m a -> TupleVect n m b

关于vector - Idris - 自定义相关数据类型的映射函数失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50768877/

相关文章:

r - 在 R 中有效地创建向量的困惑

c++ - 在类中声明成员时,指针是否比实例更好?

c++ - 如何清除这样声明的矩阵 -> vector<vector<int>>

arrays - 如何在 numpy 中对元组数组进行 bool 切片

agda - 当相关类型被 Idris 中的 lambda 抽象时,如何证明 "seemingly obvious"事实?

idris - natToFin 当有证据表明转换有效时

c++通过使用旧 vector 进行预排序来改进 vector 排序

c++ - 如何在 C++ 11 中迭代 std::tuple

c# - 将 IEnumerable<Tuple<Parent, Child>> 转换为 IEnumerable<Parent>

haskell - 是否有可能推导出教堂编码的 Nat 的归纳法?