From: Christophe Papazian <christophe.papazian@gmail.com>
To: Goswin von Brederlow <goswin-v-b@web.de>
Cc: <caml-list@inria.fr>
Subject: Re: [Caml-list] Odd failure to infer types
Date: Sat, 3 Sep 2011 12:31:59 +0200 [thread overview]
Message-ID: <E43428B9-330B-422E-9803-F10D53278FA0@gmail.com> (raw)
In-Reply-To: <87ty8uc5ph.fsf@frosties.localnet>
The type of [] is 'a list. This is (strong) polymorphism. Calling a
function 'int list -> ?' on [] doesn't not
remove the polymorphism of []. However, an '_a list array is not
polymorphism, it's just the compiler who don't know
yet the type inside the lists. And as you give him [], he can't deduce
the type.
As an example you can do this :
let s = [] in 1::s, 'a'::s, [|s|] ;;
And it still doesn't know...
Le 3 sept. 11 à 11:53, Goswin von Brederlow a écrit :
> Hi,
>
> I'm implementing a solver for the game Atomix. If you don't know it
> then
> don't worry. It isn't relevant.
>
> I split things up into submodules and now one of the submodules does
> not
> infere the right types:
>
> File "Atomix.ml", line 168, characters 11-876:
> Error: The type of this module,
> sig
> type dir = NORTH | SOUTH | WEST | EAST
> val max_moves : int
> val cache : (string, unit) Hashtbl.t
> val states :
> ('_a list * (char * int * int) array * string) list array
> val string_of_dir : dir -> string
> val print :
> (int * int * dir) list * (char * int * int) array * string
> -> unit
> val num_states : int
> end, contains type variables that cannot be generalized
>
> I believe this is wrong. In S.num_states the call to "print state"
> fixates the type for state and the "states.(d) <- state::states.(d);"
> should then fixate the missing '_a in the type for states.
>
> Anyone know why?
>
> MfG
> Goswin
>
> ----------------------------------------------------------------------
> module B = struct
> exception Outside
> let width = 14
> let height = 6
> let board = ""
> ^ " # # "
> ^ " # # "
> ^ " # "
> ^ " # # #######"
> ^ " # "
> ^ " # "
>
> let start =
> Array.of_list
> (List.sort compare
> [
> ('A', 1, 3); (* H- *)
> ('B', 10, 5); (* -O- *)
> ('C', 13, 1); (* -H *)
> ])
>
> let get board x y =
> if (x < 0) || (x >= width) || (y < 0) || (y >= height)
> then '#'
> else board.[x + y * width]
>
> let set board x y c =
> if (x < 0) || (x >= width) || (y < 0) || (y >= height)
> then raise Outside;
> let board = String.copy board
> in
> board.[x + y * width] <- c;
> board
>
> let print board =
> Printf.printf " ";
> for x = 0 to width - 1 do
> Printf.printf "%c" (char_of_int (int_of_char 'A' + x));
> done;
> Printf.printf "\n";
> Printf.printf " +--------------+\n";
> for y = 0 to height - 1 do
> Printf.printf "%d|" (y + 1);
> for x = 0 to width - 1 do
> Printf.printf "%c" board.[y * width + x];
> done;
> Printf.printf "|\n";
> done;
> Printf.printf " +--------------+\n";
> flush_all ()
> end
>
> module G = struct
> let width = 3
> let height = 1
> let atoms = "ABC"
>
> let get x y =
> if (x < 0) || (x >= width) || (y < 0) || (y >= height)
> then '~'
> else atoms.[x + y * width]
>
> let solutions =
> let rec loopy acc = function
> | -1 -> acc
> | y ->
> let rec loopx acc = function
> | -1 -> loopy acc (y - 1)
> | x ->
> let rec loopv acc sol board = function
> | -1 ->
> B.print board;
> let sol = Array.of_list (List.sort compare sol)
> in
> loopx ((sol, board)::acc) (x - 1)
> | v ->
> let rec loopu acc sol board = function
> | -1 -> loopv acc sol board (v - 1)
> | u ->
> let c = get u v
> in
> if c = ' '
> then loopu acc sol board (u - 1)
> else if B.get board (x + u) (y + v) = ' '
> then
> begin
> let board = B.set board (x + u) (y + v) c
> in
> loopu acc ((c, x + u, y + v)::sol) board (u - 1)
> end
> else loopx acc (x - 1)
> in
> loopu acc sol board (width - 1)
> in
> loopv acc [] B.board (height - 1)
> in
> loopx acc (B.width - width)
> in
> loopy [] (B.height - height)
>
> let print (sol, board) =
> B.print board;
> Array.iter
> (fun (c, x, y) ->
> Printf.printf "%c: (%c, %d)\n" c
> (char_of_int (int_of_char 'A' + x))
> (y + 1))
> sol;
> flush_all ()
> end
>
> module D = struct
> let infty = 999999
> let make_one x y =
> let d = Array.make_matrix B.width B.height infty in
> let rec loop n acc = function
> | [] ->
> if acc = []
> then d
> else loop (n + 1) [] acc
> | (u, v)::xs ->
> let rec move acc x y dx dy =
> if B.get B.board x y = ' '
> then
> let acc =
> if d.(x).(y) > n
> then
> begin
> d.(x).(y) <- n;
> (x, y)::acc
> end
> else acc
> in
> move acc (x + dx) (y + dy) dx dy
> else acc
> in
> let acc = move acc u v (-1) 0 in
> let acc = move acc u v 1 0 in
> let acc = move acc u v 0 (-1) in
> let acc = move acc u v 0 1
> in
> loop n acc xs
> in
> d.(x).(y) <- 0;
> loop 1 [] [(x, y)]
>
> let dist =
> Array.init B.width (fun x -> Array.init B.height (fun y ->
> make_one x y))
>
> let get x1 y1 x2 y2 =
> if (x1 < 0) || (x1 >= B.width) || (y2 < 0) || (y2 >= B.height)
> || (x2 < 0) || (x2 >= B.width) || (y2 < 0) || (y2 >= B.height)
> then infty
> else dist.(x1).(y1).(x2).(y2)
>
> let get_all pos =
> let d =
> Array.mapi
> (fun i (c, x1, y1) ->
> let (_, x2, y2) = B.start.(i)
> in
> get x1 y1 x2 y2)
> pos
> in
> Array.fold_left ( + ) 0 d
> end
>
> module S = struct
> type dir = NORTH | SOUTH | WEST | EAST
>
> let max_moves = 1000
> let cache = Hashtbl.create 0
> (*
> let states = ((Array.make max_moves []) :
> ((int * int * dir) list * (char * int * int) array * string)
> list array)
> *)
> let states = Array.make max_moves []
>
> let string_of_dir = function
> | NORTH -> "norden"
> | SOUTH -> "sueden"
> | WEST -> "westen"
> | EAST -> "osten"
>
> let print (moves, (_ : (char * int * int) array), board) =
> B.print board;
> List.iter
> (fun (x, y, dir) ->
> Printf.printf "zug %c %d %s,"
> (char_of_int (int_of_char 'A' + x))
> (y + 1)
> (string_of_dir dir))
> moves
>
> let num_states =
> List.fold_left
> (fun num (sol, board) ->
> let d = D.get_all sol in
> let state = ([], sol, board)
> in
> Hashtbl.add cache board ();
> states.(d) <- state::states.(d);
> print state;
> num + 1)
> 0
> G.solutions
> end
>
> let () =
> List.iter G.print G.solutions;
> Printf.printf "%d solutions\n" (List.length G.solutions)
>
> --
> Caml-list mailing list. Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
next prev parent reply other threads:[~2011-09-03 10:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-03 9:53 Goswin von Brederlow
2011-09-03 10:31 ` Christophe Papazian [this message]
2011-09-03 11:42 ` Guillaume Yziquel
2011-09-03 10:36 ` Guillaume Yziquel
2011-09-03 11:35 ` Philippe Veber
2011-09-03 11:46 ` Guillaume Yziquel
2011-09-03 12:15 ` Gabriel Scherer
2011-09-03 12:50 ` Guillaume Yziquel
2011-09-17 12:08 ` Goswin von Brederlow
2011-09-18 7:26 ` Gabriel Scherer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E43428B9-330B-422E-9803-F10D53278FA0@gmail.com \
--to=christophe.papazian@gmail.com \
--cc=caml-list@inria.fr \
--cc=goswin-v-b@web.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox