在 zipWith 中连接 "no such variable a"
concat in zipWith "no such variable a"
使用 zipWith
添加如下代码,效果很好:
zipWith (\x,y => x + y) [1,2,3] [4,5,6]
但是,使用串联而不是两个列表列表失败:
zipWith (\xs,ys => xs ++ ys) [[1],[2],[3]] [[4],[5],[6]]
有错误:
When checking argument x to constructor Prelude.List.:::
No such variable a
我发现可以无误地执行以下操作:
zipWith (++) [[1],[2],[3]] [[4],[5],[6]]
但是,我很困惑为什么与 lambda 表达式的连接失败..?
Idris> :t (++)
Prelude.List.(++) : List a -> List a -> List a
这是编译器无法确定a
值的地方。如果你只是在 REPL 中输入 [1,2,3]
,它会给它类型 List Integer
。但是 [1,2,3]
也可以是 List Int
、List Nat
类型或任何其他数字列表。如果你用 ['a','b','c']
来尝试你的例子,这种歧义就会消失并且 repl 会愉快地接受它:
Idris> zipWith (\xs, ys => xs ++ ys) [['a'],['b'],['c']] [['a'],['b'],['c']]
[['a', 'a'], ['b', 'b'], ['c', 'c']] : List (List Char)
您可以通过向类型检查器提供信息来解决最初的问题:
zipWith (\xs, ys => (++) xs ys {a=Integer}) [[1],[2],[3]] [[4],[5],[6]]
zipWith (\xs, ys => the (List Integer) (xs ++ ys)) [[1],[2],[3]] [[4],[5],[6]]
the (List (List Integer)) (zipWith (\xs, ys => xs ++ ys) [[1],[2],[3]] [[4],[5],[6]])
在大多数但最简单的情况下,统一需要一些类型声明。这就是 (++)
有效但 lambda 表达式无效的原因。前者更简单,后者有更多的抽象(即额外的功能)。
但是当在文件中编写实际代码时,编译器不会像 REPL 那样友好,并且无论如何都会要求类型声明:
-- test : List (List Integer)
test = zipWith (\xs, ys => xs ++ ys) [[1],[2],[3]] [[4],[5],[6]]
Type checking ./test.idr
test.idr:1:1:No type declaration for Main.test
使用 zipWith
添加如下代码,效果很好:
zipWith (\x,y => x + y) [1,2,3] [4,5,6]
但是,使用串联而不是两个列表列表失败:
zipWith (\xs,ys => xs ++ ys) [[1],[2],[3]] [[4],[5],[6]]
有错误:
When checking argument x to constructor Prelude.List.:::
No such variable a
我发现可以无误地执行以下操作:
zipWith (++) [[1],[2],[3]] [[4],[5],[6]]
但是,我很困惑为什么与 lambda 表达式的连接失败..?
Idris> :t (++)
Prelude.List.(++) : List a -> List a -> List a
这是编译器无法确定a
值的地方。如果你只是在 REPL 中输入 [1,2,3]
,它会给它类型 List Integer
。但是 [1,2,3]
也可以是 List Int
、List Nat
类型或任何其他数字列表。如果你用 ['a','b','c']
来尝试你的例子,这种歧义就会消失并且 repl 会愉快地接受它:
Idris> zipWith (\xs, ys => xs ++ ys) [['a'],['b'],['c']] [['a'],['b'],['c']]
[['a', 'a'], ['b', 'b'], ['c', 'c']] : List (List Char)
您可以通过向类型检查器提供信息来解决最初的问题:
zipWith (\xs, ys => (++) xs ys {a=Integer}) [[1],[2],[3]] [[4],[5],[6]]
zipWith (\xs, ys => the (List Integer) (xs ++ ys)) [[1],[2],[3]] [[4],[5],[6]]
the (List (List Integer)) (zipWith (\xs, ys => xs ++ ys) [[1],[2],[3]] [[4],[5],[6]])
在大多数但最简单的情况下,统一需要一些类型声明。这就是 (++)
有效但 lambda 表达式无效的原因。前者更简单,后者有更多的抽象(即额外的功能)。
但是当在文件中编写实际代码时,编译器不会像 REPL 那样友好,并且无论如何都会要求类型声明:
-- test : List (List Integer)
test = zipWith (\xs, ys => xs ++ ys) [[1],[2],[3]] [[4],[5],[6]]
Type checking ./test.idr
test.idr:1:1:No type declaration for Main.test