Why is `;;` giving me a syntax error in utop?

2019-07-09 22:14发布

I'm working on a short project to convert small programs from python to java and visa versa. I created the following code, and tested it in utop.

let c = 
let x = "for (int i = 0; i<10; i++)" 
and y = "for i in range(0,10):"
in function
| x -> y
| y -> x
| _ -> "Oh no!!";;

For some reason, x & y are both considered unbound, yet at the same time any parameter seems to match to x.

What order does everything need to be written in to make this work?

标签: ocaml utop
2条回答
趁早两清
2楼-- · 2019-07-09 22:33

Simply to follow up with your answer.

In pattern-matching, matching to a variable doesn't necessarily seem to match to its value.

This is the very reason why it's called pattern-matching and not value-matching.

As the name implies, pattern-matching is used to match things against patterns, not values. In the code you show in the question, you are not actually comparing anything to x or y, you are defining patterns named x and y that can match anything. See the example below:

match 2 with
| x -> "Hey, I matched!"
| _ -> "Oh, I didn't match.";;

- : string = "Hey, I matched!"

Note that this works even if x was previously defined. In the match case, the x from the pattern is actually shadowing the other one.

let x = 42 in
match 1337 with
| x -> Printf.printf "Matched %d\n!" x
| _ -> ();;

Matched 1337!
- : unit = ()

On the other hand, the pattern i when i = x is actually matching against the value of the outer variable x, which is why the code in your self-answer works. But this is not what patterns are for anyway.

What you're actually trying to do is not a pattern-matching, it is a simple conditional statement.

let c argument = 
  let x = "for (int i = 0; i<10; i++)"  in
  let y = "for i in range(0,10):" in
  if argument = x then y
  else if argument = y then x
  else "Oh no!";;

val c : string -> string = <fun>

And here it is in action:

c "for (int i = 0; i<10; i++)";;
- : string = "for i in range(0,10):"

c "for i in range(0,10):";;
- : string = "for (int i = 0; i<10; i++)"

c "whatever";;
- : string = "Oh no!"

Also, don't use and unless you're defining mutually recursive values.

查看更多
倾城 Initia
3楼-- · 2019-07-09 22:42

So I'm not fully understanding WHY it works this way, but I at least understand how it works.

My issue was that, in pattern-matching, matching to a variable doesn't necessarily seem to match to its value.

In short, I should be typing

 function
 | i when i = x -> y
 | i when i = y -> x
 | _ -> "Oh no!!";;

If anyone can shed some more light on what differentiates "x -> y" from I when I = x -> y, I am still curious about that.

Otherwise, thanks @ghilesZ for sending me the links I needed to figure this one out! And thanks @BahmanMovaqar for helping me understand the priority of statements a bit better.

查看更多
登录 后发表回答