2014-11-09 45 views
0

这只是一个练习(我意识到下面提到的功能已经在List中实现)。以折线定义列表长度

假设我有一个包含以下行

val length : 'a list -> int 
val fold : init:'acc -> f:('acc -> 'a -> 'acc) -> 'a list -> 'acc 

接口......而我实现fold这样的:

let rec fold ~init ~f l = 
    match l with 
    | []  -> init 
    | h :: t -> fold ~init:(f init h) ~f:f t 

我希望现在能够实现length像这

let length = fold ~init:0 ~f:(fun c _ -> (c + 1)) 

...但编译呃与

Values do not match: 
    val length : '_a list -> int 
    is not included in 
    val length : 'a list -> int 

当然抱怨,我知道我可以实现length这样

let length l = fold ~init:0 ~f:(fun c _ -> (c + 1)) l 

...但我不明白为什么我不能从两边去掉后l=

我哪里错了?

回答

1

这是价值限制。你的长度定义在技术意义上不是一个价值。 Stack Overflow已经在这里讨论了这个问题。我会寻找一个好的。

这是一个相当不错的:

Why does a partial application have value restriction?

+0

深的东西...谢谢! – kjo 2014-11-09 00:34:58

+1

这不是* *深*:胶囊摘要是,除非你确定它是安全的,否则你不能使事物变成多态。在可变数据的语言(如OCaml)中,它并不总是安全的。 “价值限制”是何时安全的近似值。这不是一个特别接近的近似值,但它很容易记住。 – 2014-11-09 04:37:34

+0

我猜想,我有一个“短脑袋”,因为对于我来说,“价值限制”是一个解决方案(更不用说是一个很好的解决方案),对于在支持多态的语言中实现类型推断的问题类型和可变数据。顺便说一下,我希望OCaml的设计师们不会因为易于记忆而定居下来,而是为了获得最大的表现力,毕竟,使用电脑的重点在于超越我们能做的事情。 – kjo 2014-11-09 14:05:10