使用模块进行类型推断



当试图在模块中为定义为int * int类型的变量赋值时:

let start : MazeProblem.state= (0,0)

我得到一个错误消息,类型不匹配。(问题出现在尝试搜索库从:https://www.lri.fr/filliatr/ftp/ocaml/ds/search.ml.html)

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)

我希望OCaml的类型推断检测到(0,0)int*int类型与定义的结构兼容。

根据Glennsl在评论中的建议,并通过查看链接的FunctionalProblem模块签名(如下所示)确认,MazeProblem.state的类型为abstract

module type FunctionalProblem = sig
type state
type move
val success : state -> bool
val moves : state -> (move * state) list
type table
val create : unit -> table
val add : table -> state -> unit
val mem : table -> state -> bool
val clear : table -> unit
end

看下面一个更简单的例子,我们可以看到A签名的应用使得C摘要中的t类型。在B不是抽象,所以我们可以直接将intB.f一起使用,而在C.f中这样做会导致编译错误。

# module type A = sig
type t
val f : t -> t
end
module B = struct
type t = int
let f x = x + 1
end
module C : A = B;;
module type A = sig type t val f : t -> t end
module B : sig type t = int val f : t -> t end
module C : A
# B.f 5;;
- : int = 6
# C.f 5;;
Error: This expression has type int but an expression was expected of type C.t

或者,我们可以公开t的类型。

# module D : A with type t = int = B;;
module D : sig type t = int val f : t -> t end
# D.f 5;;
- : int = 6

最新更新