Computer Science Canada

pattern matching issue

Author:  Fonzie [ Mon Mar 02, 2009 6:48 pm ]
Post subject:  pattern matching issue

How do I match a pattern without assigning the variable I'm matching a new value? For example Let's say I want to make sure t is of the form Node (i,t1,t2), but then I want to leave t alone and do something else. So I guess I'm looking for a kind of if statement that can match patterns.

Ocaml:
if t = Node (i,t1,t2) then
do some stuff


Is this possible?

Author:  wtd [ Mon Mar 02, 2009 7:12 pm ]
Post subject:  RE:pattern matching issue

Language?

Author:  Fonzie [ Mon Mar 02, 2009 7:26 pm ]
Post subject:  Re: pattern matching issue

ocaml

Author:  wtd [ Mon Mar 02, 2009 7:33 pm ]
Post subject:  RE:pattern matching issue

code:
match t with Node (i, t1, t2) -> blah ()

Author:  Fonzie [ Mon Mar 02, 2009 7:48 pm ]
Post subject:  Re: pattern matching issue

my problem with that though is that t is then assigned the value of blah(). I'm trying to find a way so that t is not assigned a new value.

Author:  wtd [ Mon Mar 02, 2009 7:57 pm ]
Post subject:  RE:pattern matching issue

code:
# type foo = Node of int * int * int;;
type foo = Node of int * int * int
# let t = Node (1, 2, 3);;
val t : foo = Node (1, 2, 3)
# match t with Node (a, b, c) -> t;;
- : foo = Node (1, 2, 3)
# t;;
- : foo = Node (1, 2, 3)
#

Author:  Fonzie [ Mon Mar 02, 2009 8:14 pm ]
Post subject:  Re: pattern matching issue

But then can I use it as I previously mentioned? Let me show you in pseudo code what I'm trying to do.

Ocaml:
if t is of the form node (a,b,c) then
run a whole bunch of functions
else if t is of the form leaf (a) then
run a whole bunch of different functions


I'm trying to Identify what type t is and take different steps depending on the type.

Author:  wtd [ Mon Mar 02, 2009 8:28 pm ]
Post subject:  RE:pattern matching issue

code:
# type 'a foo = Leaf | Node of 'a;;
type 'a foo = Leaf | Node of 'a
# let bar t =     
      match t with
          Leaf -> (print_string "A leaf!"; print_newline ())
        | Node n -> (print_string "A node!"; print_newline ());;
val bar : 'a foo -> unit = <fun>
# bar (Leaf);;
A leaf!
- : unit = ()
# bar (Node 4);;
A node!
- : unit = ()
#

Author:  Fonzie [ Mon Mar 02, 2009 8:51 pm ]
Post subject:  Re: pattern matching issue

I think I've perhaps been communicating something wrong. Thank you for your patience and help up to this point. Here is my actual function.

Ocaml:
let rec sum t =
match t with
    Leaf i -> i
  | Node (i, t1, t2) -> i + (sum t1) + (sum t2);;


let sum2 t =
let rec loop previous instructions sum t =
match t with
Node (i,t1,t2)->

if (List.hd instructions) = 3 then
sum

else if (List.hd instructions) = 2 then
loop(t,0::(3::instructions), sum+i, t1)

else if (List.hd instructions) = 0 then
loop(t,0::instructions, sum+i, t1)

else
loop(t,1::instructions, sum+i, t2)

|Leaf i ->

if (List.hd instructions) = 0 then
loop(t,1::(List.tl instructions), sum+i, t)
else
loop(t,List.tl (List.tl instructions), sum+i, t)

in
loop t [2] 0 t;;


I'm getting type complaints from the compiler because sum and loop(t,0::(3::instructions), sum+i, t1) are different types I think. I'm just trying to find a way to verify type without getting complaints.

Author:  wtd [ Mon Mar 02, 2009 9:54 pm ]
Post subject:  RE:pattern matching issue

Can you provide the type declaration?

Author:  Fonzie [ Mon Mar 02, 2009 10:04 pm ]
Post subject:  Re: pattern matching issue

sure thing

Ocaml:
type tree =
Leaf of int
| Node of int * tree * tree;;

Author:  wtd [ Mon Mar 02, 2009 10:36 pm ]
Post subject:  RE:pattern matching issue

First off, let's format that nicely. Just because O'Caml has free-form syntax doesn't mean we need to be sloppy.

code:
type 'a tree =
    Leaf of 'a
  | Node of 'a * 'a tree * 'a tree

let rec sum (t : int tree) : int =
    match t with
        Leaf i -> i
      | Node (i, t1, t2) -> i + sum t1 + sum t2

let sum2 (t : int tree) : int =
    let rec loop previous instructions sum t =
        match t with
            Node (i, t1, t2)->
                match List.hd instructions with
                    3 -> sum
                  | 2 -> loop t (0 :: 3 :: instructions) (sum + i) t1
                  | 0 -> loop t (0 :: instructions) (sum + i) t1
                  | _ -> loop t (1 :: instructions) (sum + i) t2
          | Leaf i ->
                if List.hd instructions = 0 then
                    loop t (1 :: List.tl instructions) (sum + i) t
                else
                    let tl2 lst = List.tl (List.tl lst)
                    in
                        loop t (tl2 instructions) (sum + i) t
    in
        loop t [2] 0 t;;


I've also added some type annotations to aid in figuring out where this is breaking.

Author:  wtd [ Mon Mar 02, 2009 11:04 pm ]
Post subject:  RE:pattern matching issue

Oops.

code:
type 'a tree =
    Leaf of 'a
  | Node of 'a * 'a tree * 'a tree

let rec sum (t : int tree) : int =
    match t with
        Leaf i -> i
      | Node (i, t1, t2) -> i + sum t1 + sum t2

let sum2 (t : int tree) : int =
    let rec loop previous instructions sum t =
        match t with
            Node (i, t1, t2) ->
                (match List.hd instructions with
                     3 -> sum
                   | 2 -> loop t (0 :: 3 :: instructions) (sum + i) t1
                   | 0 -> loop t (0 :: instructions) (sum + i) t1
                   | _ -> loop t (1 :: instructions) (sum + i) t2)
          | Leaf i ->
                if List.hd instructions = 0 then
                    loop t (1 :: List.tl instructions) (sum + i) t
                else
                    let tl2 lst = List.tl (List.tl lst)
                    in
                        loop t (tl2 instructions) (sum + i) t
    in
        loop t [2] 0 t;;

Author:  Fonzie [ Tue Mar 03, 2009 8:20 pm ]
Post subject:  Re: pattern matching issue

Alright, thank you very much for all the help you've given me.

Author:  wtd [ Tue Mar 03, 2009 9:00 pm ]
Post subject:  RE:pattern matching issue

For what it's worth, a little bit different syntactic take on things.

code:
type 'a tree =
    Leaf of 'a
  | Node of 'a * 'a tree * 'a tree

let rec sum (t : int tree) : int =
    match t with
        Leaf i -> i
      | Node (i, t1, t2) -> i + sum t1 + sum t2

let sum2 (t : int tree) : int =
    let rec loop previous instructions sum t =
        let top_instruction = List.hd instructions
        in
            match t with
                Node (i, t1, t2) when top_instruction = 3 -> sum
              | Node (i, t1, t2) when top_instruction = 2 ->
                    loop t (0 :: 3 :: instructions) (sum + i) t1
              | Node (i, t1, t2) when top_instruction = 0 ->
                    loop t (0 :: instructions) (sum + i) t1
              | Node (i, t1, t2) -> loop t (1 :: instructions) (sum + i) t2
              | Leaf i ->
                    if List.hd instructions = 0 then
                        loop t (1 :: List.tl instructions) (sum + i) t
                    else
                        let tl2 lst = List.tl (List.tl lst)
                        in
                            loop t (tl2 instructions) (sum + i) t
    in
        loop t [2] 0 t;;


: