Skip to content

Instantly share code, notes, and snippets.

@FlandreDaisuki
Created August 23, 2021 15:46
Show Gist options
  • Save FlandreDaisuki/dbc5463df3ac5cc55ae2746746559dc7 to your computer and use it in GitHub Desktop.
Save FlandreDaisuki/dbc5463df3ac5cc55ae2746746559dc7 to your computer and use it in GitHub Desktop.
Why?
module Student = struct
type t = { id: int; name: string; }
let init (id, name) = { id = id; name = name; }
end
;;
let alice = Student.init(0, "Alice")
(* val alice : Student.t = {Student.id = 0; name = "Alice"} *);;
let () = Printf.printf "Hello, %s\n" alice.name
;;
let () = List.iter (fun s ->
Printf.printf "Hello, %s\n" s.name
(* ^^^^ *)
(* Error: Unbound record field name *)
) [alice]
;;
@FlandreDaisuki
Copy link
Author

FlandreDaisuki commented Aug 24, 2021

I think I get the point.

# List.iter;;
- : ('a -> unit) -> 'a list -> unit = <fun>
# let f x = ();;
val f : 'a -> unit = <fun>

then

# List.iter f;;
- : '_weak1 list -> unit = <fun>

The f is not binding any type to x until we pass a 'a list.


There are 2 solutions to solve this by my knowledge:

module Student = struct
  type t = { id: int; name: string; }
  let init (id, name) = { id = id; name = name; }
+ let name s = s.name
end
;;

let () = List.iter (fun s ->
-  Printf.printf "Hello, %s\n" s.name
+  Printf.printf "Hello, %s\n" (Student.name s)
) [alice]
;;

and thank @yawaramin helps

- let () = List.iter (fun s ->
+ let () = List.iter (fun (s: Student.t) ->
  Printf.printf "Hello, %s\n" s.name
) [alice]
;;

@FlandreDaisuki
Copy link
Author

ohh, I get confused again when I meet the problem as following:

type student = { id: int; name: string; };;

let bob = { id = 1; name = "Bob"};;
(* val bob : student = {id = 1; name = "Bob"} *);;

let () = Printf.printf "Hello, %s\n" bob.name
;;

let () = List.iter (fun s ->
  Printf.printf "Hello, %s\n" s.name
) [bob]
;;

It can be compiled and run as expected… why?

@FlandreDaisuki
Copy link
Author

OK. According to the module section of Real World OCaml, we need open the module signature.

We can expose it after module definition

module Student = struct
  type t = { id: int; name: string; }
  let init (id, name) = { id = id; name = name; }
end
;;

+ open Student;;

Or, expose it in minimum

- let () = List.iter (fun s ->
+ let () = let open Student in List.iter (fun s ->
  Printf.printf "Hello, %s\n" s.name
) [alice]
;;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment