1

所以我正在写一个flatten fn,我做到了:

fun flatten ls = List.foldr op @ [] ls

而且我意识到命名变量ls应该是不必要的,相反我可能只是部分地 apply foldr。但这打破了:

val flatten = List.foldr op @ []

是什么让它一团糟?我似乎必须fun为声明和部分应用推断类型foldr

类似的 sum 函数有效,这让我想知道为什么@特别不起作用:

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)
4

2 回答 2

3

我有点不清楚你到底指的是什么错误。您在标题中提到您收到“操作员域错误”,但是您的代码只会产生“值限制”警告。有一个很大的不同。

值限制是比较复杂的事情之一,但本质上它是为了在语言中有引用时保持类型安全。

MLton wiki 有一篇关于价值限制的精彩文章,其中涵盖了价值限制存在的原因、不必要的拒绝程序、价值限制的替代方案以及如何使用价值限制。

于 2013-04-26T00:55:40.300 回答
1

AJ,Jesper 的文章既解释了您看到的警告,又富有洞察力,但是对于您的问题的更实际的解决方案,您可能想试试这个:

val flatten = foldr op @ ([]:int list);

我相信这应该可以解决您的问题。

编辑:我之所以选择int list显式类型,是因为我观察到了您的警告消息的性质,并从那里推断出int list您所需要的。[=

注意:上述解决方案破坏了多态性并将输入限制为所选类型。

于 2013-04-26T03:33:38.827 回答