【问题标题】:reasonml type higher order functionreasonml 类型的高阶函数
【发布时间】:2020-02-16 09:29:54
【问题描述】:

给定以下模块,编译器会引发错误

  41 │ };
  42 │ 
  43 │ module TestB = {
  44 │   let minFn = (a, b) => a < b ? a : b;
   . │ ...
  54 │   let max = reduceList(maxFn);
  55 │ };
  56 │ 
  57 │ // module Number = {

  The type of this module contains type variables that cannot be generalized:
  {
    let minFn: ('a, 'a) => 'a;
    let maxFn: ('a, 'a) => 'a;
    let reduceList: ('a, list('b)) => option('b);
    let min: list('_a) => option('_a);
    let max: list('_a) => option('_a);
  }

这似乎是因为我只是将部分参数应用于reduceList。现在,我得到了一些关于价值限制的信息,在我看来,这就是这里发生的事情。

我已经尝试显式键入函数 minmax 并在其中显式键入模块作为一个整体,因为我认为根据 this section about value restriction 应该这样解决这个问题.但是,这似乎没有什么区别。

module TestB = {
  let minFn = (a, b) => a < b ? a : b;
  let maxFn = (a, b) => a > b ? a : b;
  let reduceList = (comp, numbers) =>
    switch (numbers) {
    | [] => None
    | [head] => Some(head)
    | [head, ...tail] => Some(List.fold_left(minFn, head, tail))
    };

  let min = reduceList(minFn);
  let max = reduceList(maxFn);
};

另一方面...类型的前导 _ 在这里有什么特别的含义吗?

【问题讨论】:

    标签: ocaml reason partial-application value-restriction


    【解决方案1】:

    这确实是因为价值限制。我看不到您所引用的文档部分说明了有关能够使用类型注释来避免它的任何内容,尽管在我看来它似乎也应该如此。希望这里有一些经验丰富的 OCamler 可以解释为什么它没有。

    据我所知,除非类型注释不包含任何类型变量,从而消除多态性,否则它不会,而且我认为这不是您想要的。解决此问题的最简单方法是使用 eta 扩展,即使参数显式而不是使用部分应用程序。这证明了两者:

    module TestB = {
      let minFn = (a, b) => a < b ? a : b;
      let maxFn = (a, b) => a > b ? a : b;
      let reduceList = (comp, numbers) =>
        switch (numbers) {
        | [] => None
        | [head] => Some(head)
        | [head, ...tail] => Some(List.fold_left(minFn, head, tail))
        };
    
      let min = x => reduceList(minFn, x);
      let max : list(int) => option(int) = reduceList(maxFn);
    };
    

    '_a 中的下划线 _ 仅表示它是一个弱类型变量,如您参考的文档中所述:

    名称以 _weak 前缀(如 '_weak1)开头的类型变量是弱多态类型变量,有时简称为弱类型变量。弱类型变量是当前未知的单一类型的占位符。一旦知道占位符类型 '_weak1 后面的特定类型 t,所有出现的 '_weak1 都将被 t 替换。

    【讨论】:

    • 你是对的,不可能(在 OCaml 中)使用类型注释删除弱多态类型变量。
    • 明确一点,eta 扩展是x =&gt; reduceList(minFn, x);let max: list(int) =&gt; option(int) = reduceList(maxFn); 只是简单地删除多态性对吗?
    • @DanielPotensky 正确!
    猜你喜欢
    • 2012-10-25
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    相关资源
    最近更新 更多