所以我正在写一个扁平的fn,我明白了:
fun flatten ls = List.foldr op @ [] ls
我意识到,变量ls
的命名应该是不必要的,而我可能只是在paritally应用foldr
。但这打破了:
val flatten = List.foldr op @ []
是什么让它搞砸了?我似乎必须推断出fun
声明和部分应用foldr
的 typ 。
类似的求和函数有效,这让我想知道为什么@
特别不起作用:
val sum = List.foldr op + 0
编辑:我收到的错误:
- val flatten = List.foldr op @ [];
stdIn:1.6-2.13 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val flatten = fn : ?.X1 list list -> ?.X1 list
- flatten [[1], [1]];
stdIn:3.1-3.19 Error: operator and operand don't agree [literal]
operator domain: ?.X1 list list
operand: int list list
in expression:
flatten ((1 :: nil) :: (1 :: nil) :: nil)
答案 0 :(得分:3)
我有点不清楚你指的是什么错误。您在标题中提到您收到“操作员域错误”,但是您的代码只会产生“值限制”警告。有很大的不同。
价值限制是让你了解的更复杂的事情之一,但实质上它是在语言中引用时保留类型安全的。
MLton wiki在value restriction上有一篇很棒的文章,其中涵盖了为什么存在价值限制,不必要的拒绝程序,价值限制的替代方案以及如何使用价值限制。
答案 1 :(得分:1)
AJ, Jesper的文章既解释了您所看到的警告,又具有洞察力,但为了解决您的问题,您可能想尝试这样做:
val flatten = foldr op @ ([]:int list);
我认为应该解决你的问题。
编辑:我选择了int list
作为显式类型,因为我观察了您的警告消息的性质,并从那里推断出,int list
就是您所需要的。 [=
注意:上述解决方案会破坏多态性并将输入限制为所选类型。