推断值和矢量长度之间的类型不匹配

时间:2016-01-13 19:04:48

标签: idris

试图在Type driven development with Idris中解决关于矩阵乘法的练习,这让我陷入了烦人的问题。

到目前为止,我最终定义了一组辅助函数,如下所示:

morexs : (n : Nat) -> Vect m a -> Vect n (Vect m a)
morexs n xs = replicate n xs

mult_cols : Num a => Vect m (Vect n a) -> Vect m (Vect n a) -> Vect m (Vect n a)
mult_cols xs ys = zipWith (zipWith (*)) xs ys

mult_mat_helper : Num a => Vect m a -> Vect n (Vect m a) -> Vect n a
mult_mat_helper xs ys =
    let len = the Nat (length ys) in
    map sum (mult_cols (morexs len xs) ys)

然而,类型检查员抱怨推断值和给定值之间存在类型不匹配的情况。在replicate (length ys) xs

When checking right hand side of mult_mat_helper with expected type
        Vect n a

When checking argument n to function Main.morexs:
        Type mismatch between
                n (Inferred value)
        and
                len (Given value)

        Specifically:
                Type mismatch between
                        n
                and
                        length ys

为什么会发生这种不匹配? ys的长度为n,我复制n次,所以我没有看到问题:/

最初我定义了我的功能:

mult_mat_helper : Num a => Vect m a -> Vect n (Vect m a) -> Vect n a
mult_mat_helper xs ys =
    let
        xs2 = replicate (length ys) xs
        zs = zipWith (zipWith (*)) xs2 ys
    in
    map sum zs

但出现以下错误:

When checking right hand side of mult_mat_helper with expected type
        Vect n a

When checking argument m to function Prelude.Functor.map:
        a is not a numeric type

我尝试在repl中运行一些测试数据的所有步骤,一切正常......然而,代码拒绝通过类型检查器

1 个答案:

答案 0 :(得分:3)

length的类型为

Data.Vect.length : Vect n a -> Nat

它返回一些Nat。类型检查器不知道Nat实际上是n - 所以它不能在两个值之间统一。实际上,你甚至不需要length。文档说

  

注意:这仅在您尚未静态了解时才有用   长度,你想避免匹配隐含的参数   擦除原因。

因此,我们可以匹配隐式参数而不是length

mult_mat_helper : Num a => Vect m a -> Vect n (Vect m a) -> Vect n a
mult_mat_helper {n} xs ys = map sum (mult_cols (morexs n xs) ys)