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

OCaml中matrix_game子类的insert与print方法异常求助

问题排查与修复方案

核心问题分析

  1. 数据不一致:sudoku类同时维护了父类的matrix和自身的m两个独立数组,insert修改的是m,但print调用父类方法打印的是matrix,导致插入的数据无法被输出。
  2. 泛型未绑定:继承matrix_game时使用未具体化的['a]泛型,而sudoku明确是int类型矩阵,引发类型推断异常。
  3. 打印函数无效:传递给父类的打印函数是(fun x -> print_char ' '),仅输出空格,完全无法显示矩阵中的数值。
  4. 冗余方法重写:is_out_of_bounds方法没必要硬编码9,父类已基于rows和cols实现通用判断,冗余重写易引发错误。

修复后的完整代码

class virtual ['a] matrix_game m pf = 
  object 
    val matrix : 'a array array = m
    val rows = Array.length m
    val cols = Array.length m.(0)
    val print_function : 'a -> unit = pf

    method print = 
      for _ = 0 to cols do 
        print_char '-' 
      done;
      print_char '\n';
      Array.iter 
        (fun row ->
           print_char '|';
           Array.iter (fun elem -> print_function elem; print_char ' ') row;
           print_endline "|") 
        matrix;
      for _ = 0 to cols do 
        print_char '-' 
      done;
      print_char '\n'

    method private is_out_of_bounds (y, x) = 
      y >= rows || y < 0 || x >= cols || x < 0

    method virtual private is_legal : int * int -> 'a -> bool
    method virtual insert : int * int -> 'a -> unit
  end

class sudoku = 
  object(self)
    inherit [int] matrix_game (Array.make_matrix 9 9 0) (fun x -> print_int x) as parent

    method private check_value v = v > 0 && v < 10

    method private check_existence (y, x) v = 
      let empty_value = 0 in
      if not (self#is_out_of_bounds (y, x)) then
        self#matrix.(y).(x) <> empty_value
      else
        false

    method private is_legal (y, x) v = 
      not (self#is_out_of_bounds (y, x)) && 
      self#check_value v && 
      not (self#check_existence (y, x) v)

    method insert (y, x) v = 
      if self#is_legal (y, x) v then
        self#matrix.(y).(x) <- v
      else
        print_endline "Illegal move!"

    method print : unit = 
      parent#print
  end

关键修复点说明

  • 移除冗余的val m:直接复用父类的matrix数组,通过self#matrix访问,确保insert和print操作同一数据源。
  • 具体化泛型:继承时指定[int],明确sudoku为int类型矩阵,解决类型推断问题。
  • 修复打印逻辑:将打印函数改为(fun x -> print_int x),并在父类print方法中添加空格分隔元素,提升输出可读性。
  • 删除冗余重写:移除自定义的is_out_of_bounds方法,复用父类通用实现,避免硬编码数值。
  • 简化检查逻辑:check_existence直接调用父类的边界判断方法,减少重复代码。

测试验证

运行你的测试代码:

let s1 = new sudoku ;; 
s1#insert (3,3) 5 ;; 
s1#print;; 

将正确在(3,3)位置插入5,并输出包含该数值的9x9矩阵,示例输出:

----------
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 5 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 0 0 |
----------

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:02:14