OCaml模块类型不匹配:int*int无法赋值给MazeProblem.state
类型不匹配问题:
int*int无法赋值给MazeProblem.state 当执行以下代码时出现类型不匹配错误:
let start : MazeProblem.state= (0,0)
错误信息
File "search_test1.ml", line 34, characters 33-38:
Error: This expression has type 'a * 'b
but an expression was expected of type MazeProblem.state
相关代码
#use "search.ml" module Maze_FunctionalProblem = struct type move = string type state = int * int let success s = let (x,y) = s in if (x==y && x==1) then true else false let moves (s:state) : (move * state) list = match s with | (0,0) -> [ ("S", (1,0));("E",(0,1)) ] | (0,1) -> [ ("S", (1,1));("W",(0,0)) ] | (1,0) -> [ ("N", (0,0));("E",(1,1)) ] | (1,1) -> [ ("N", (0,1));("W",(1,0)) ] type table = (state, int) Hashtbl.t let create (u:unit) = Hashtbl.create 100 let add (t:table) (s:state) : unit = Hashtbl.add t s 1 let mem (t:table) (s:state ): bool = Hashtbl.mem t s let clear (t:table) = Hashtbl.clear t end module MazeProblem : FunctionalProblem = Maze_FunctionalProblem module Test=FunctionalDFS(MazeProblem) let start : MazeProblem.state= (0,0)
问题原因与解决方法
问题根源在于模块约束module MazeProblem : FunctionalProblem = Maze_FunctionalProblem:当用FunctionalProblem签名约束模块时,OCaml会隐藏签名中未公开的类型细节。FunctionalProblem签名里仅将state声明为抽象类型,未暴露其int*int的具体结构,因此外部无法直接用元组(0,0)赋值给MazeProblem.state。
有三种解决思路:
- 去掉签名约束:直接写成
module MazeProblem = Maze_FunctionalProblem,让模块保留所有类型细节。 - 扩展签名暴露类型:定义包含具体类型的签名,既满足
FunctionalProblem接口要求,又公开state结构:module type MazeProblemSig = sig include FunctionalProblem type state = int * int end module MazeProblem : MazeProblemSig = Maze_FunctionalProblem - 提供构造函数:在模块内添加构造函数,避免暴露类型细节:
同时在module Maze_FunctionalProblem = struct (* 原有代码不变 *) let make_state x y = (x, y) endFunctionalProblem签名中添加val make_state : int -> int -> state,外部通过MazeProblem.make_state 0 0创建state值。
内容的提问来源于stack exchange,提问作者atzensepp
相关产品推荐
相关产品推荐

