试图在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中运行一些测试数据的所有步骤,一切正常......然而,代码拒绝通过类型检查器
答案 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)