【问题标题】:type of Idris chop伊德里斯印章的类型
【发布时间】:2019-02-13 23:11:35
【问题描述】:

我正在尝试在 Idris 中编写 chop 函数。 Haskell 等价物看起来像:

chop :: Int -> [t] -> [[t]]
chop n [] = []
chop n v = take n v : chop n (drop n v)

我在 Idris 的初步尝试如下:

chop : (n : Nat) -> Vect (k * n) a -> Vect k (Vect n a)
chop n Nil = Nil
chop n v = (take n v) :: (chop n (drop n v))

类型检查错误:

Type mismatch between
               Vect 0 a (Type of [])
       and
               Vect (mult k n) a (Expected type)

       Specifically:
               Type mismatch between
                       0
               and
                       mult k n

【问题讨论】:

    标签: types functional-programming idris dependent-type


    【解决方案1】:

    k 仍然可以设置为参数,即chop {k=3} Z [] 将导致[[], [], []] : Vect 3 (Vect Z a)。您的实现将返回chop n Nil = [],因此 Idris 的类型系统正确地抱怨。 :-)

    你需要考虑k

    chop : (n : Nat) -> Vect (k * n) a -> Vect k (Vect n a)
    chop {k} n v = ?hole
    

    如果你想要实际的实现,这里有一个剧透:

    这和你的很相似。因为mult 在第一个参数上递归(在这种情况下为k),所以chop 的递归也应该遵循k
    chop {k = Z} n v = []
    chop {k = (S k)} n v = take n v :: chop n (drop n v)

    另一种方法是指定你想要多少块而不是每个块有多大。

    chop' : (k : Nat) -> Vect (k * n) a -> Vect k (Vect n a)
    chop' Z v = []
    chop' {n} (S k) v = take n v :: chop k (drop n v)
    

    n 需要在调用takedrop 的范围内。

    【讨论】:

    • 我了解chop {k = Z} n v = [],但chop {k = (S k)} n v = take n v :: chop n (drop n v) 不太了解,您能否详细说明一下
    • 你能具体说明什么是难以理解的吗?如何从chop {k = S k} … = ?hole 到实现?
    • n > 0 不是只有一个有效的k 值吗?无论如何要重写chop所以不必指定k
    • 一旦定义了k 的情况(k = Z),您也应该在其他情况下定义它。否则 Idris 可能知道也可能不知道 k != Z 在其他情况下。另外,因为k 是递归的参数(因为Vect k … 是结果),你需要拆分它。您可以使用 chop' : (k : Nat) -> Vect (k * n) a -> Vect k (Vect n a) 等另一个函数删除 n
    • 我不确定chop' 会是什么样子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    相关资源
    最近更新 更多