You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算正整数除数列表时的类型错误如何修复?

OCaml函数类型不匹配问题解决

题目要求

定义函数libDiv,用于计算某个正整数的自然数除数列表。
首先定义libDivInf,要求libDivInf n i返回n的所有小于等于i的除数列表,其类型标注为:

libDivInf : int -> int -> int list

示例:

(liDivInf 20 4) = [4;2;1] 
(liDivInf 7 5)  = [1] 
(liDivInf 4 4)  = [4;2;1]

尝试代码

let liDivInf : int -> int -> int list = function 
    (n,i) -> if i = 0 then []   (*ERROR LINE*)
      else 
      if (n mod i) = 0 (* if n is dividable by i *) 
      then 
        i::liDivInf n(i-1)
      else 
        liDivInf n(i-1);; 

let liDiv : int -> int list = function 
    n -> liDivInf n n;; 

错误信息

ERROR: this pattern matches values of type 'a * 'b ,but a pattern
was expected which matches values of type int

错误原因

这个错误的核心是类型不匹配:

  • 你用function (n,i)的写法,是在匹配元组类型('a * 'b),也就是把参数当作一个包含两个元素的元组来处理。
  • 但你给liDivInf标注的类型是int -> int -> int list,这是柯里化的双参数函数,OCaml中柯里化函数和元组参数函数属于不同的类型分支,因此编译器报错。

另外还有一个语法错误:liDivInf n(i-1)会被OCaml解析为「把n当作函数,传入i-1作为参数」,正确的函数调用应该用空格分隔参数:liDivInf n (i-1)。

修复方案

因为题目明确要求libDivInf的类型是int -> int -> int list,所以推荐采用保持柯里化类型的修复方式:

修复后的代码

let liDivInf : int -> int -> int list = fun n i -> 
    if i = 0 then []
    else if (n mod i) = 0
    then i :: liDivInf n (i-1)
    else liDivInf n (i-1);; 

let liDiv : int -> int list = function 
    n -> liDivInf n n;; 

说明

  • 把function (n,i)改成fun n i ->,符合柯里化函数的参数定义方式,和标注的类型完全匹配。
  • 修正函数调用写法,将liDivInf n(i-1)改为liDivInf n (i-1),确保OCaml正确识别是调用liDivInf并传入两个参数n和i-1。

内容的提问来源于stack exchange,提问作者Axq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:30:54