Google Groups Home
Help | Sign in
Question on Variant Types
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  10 messages - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
Jonathan Roewen  
View profile
 More options Jun 28 2006, 12:52 pm
Newsgroups: fa.caml
From: "Jonathan Roewen" <jonathan.roe...@gmail.com>
Date: Wed, 28 Jun 2006 16:52:02 UTC
Local: Wed, Jun 28 2006 12:52 pm
Subject: Re: [Caml-list] Question on Variant Types

# let bar_of_foo t = (t : foo :> bar);;
val bar_of_foo : foo -> bar = <fun>
# g (bar_of_foo c);;
- : bar = `Tree (`Tree `Nil)

Jonathan

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jonathan Roewen  
View profile
 More options Jun 28 2006, 12:53 pm
Newsgroups: fa.caml
From: "Jonathan Roewen" <jonathan.roe...@gmail.com>
Date: Wed, 28 Jun 2006 16:53:19 UTC
Local: Wed, Jun 28 2006 12:53 pm
Subject: Re: [Caml-list] Question on Variant Types

> # let bar_of_foo t = (t : foo :> bar);;
> val bar_of_foo : foo -> bar = <fun>
> # g (bar_of_foo c);;
> - : bar = `Tree (`Tree `Nil)

I should've added that without needing an intermediate function, you
can also do:
g (c : foo :> bar);;

> Jonathan

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jonathan Roewen  
View profile
 More options Jun 28 2006, 7:54 pm
Newsgroups: fa.caml
From: "Jonathan Roewen" <jonathan.roe...@gmail.com>
Date: Wed, 28 Jun 2006 23:54:04 UTC
Local: Wed, Jun 28 2006 7:54 pm
Subject: Re: [Caml-list] Question on Variant Types

> Followup question:
> Given I have:
> type foo = [`A | `B of int | `C of char]
> type bar = [`B of int | `C  of char| `D]

> and a function
> let f (x : foo) : bar =
> match x with
>     `A -> `D
>    |`B _
>    |`C _ -> (x : bar)

> Is there any way to properly coerce this using the restricted variant
> information of x? Or do I have to duplicate code and reconstruct x?

let f (x : foo) : bar = match x with
| `A -> `D
| `B _ | `C _ as x -> (x : bar)

Jonathan

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jonathan Roewen  
View profile
 More options Jun 28 2006, 11:12 pm
Newsgroups: fa.caml
From: "Jonathan Roewen" <jonathan.roe...@gmail.com>
Date: Thu, 29 Jun 2006 03:12:19 UTC
Local: Wed, Jun 28 2006 11:12 pm
Subject: Re: [Caml-list] Question on Variant Types
On 6/29/06, Seth J. Fogarty <sfoga...@gmail.com> wrote:

Only thing I could think of was:

# let rec occurs i = function
  | `A j -> i = j
  | `C (f,b) -> (occurs_foo i f) || (occurs_bar i b)
  | otherwise -> false
  and occurs_foo i = function
  | `A j -> i = j
  | otherwise -> false
  and occurs_bar i = function
  | `A j -> i = j
  | `C (f,b) -> (occurs_foo i f) || (occurs_bar i b)
  | otherwise -> false;;
val occurs :
  'a ->
  [> `A of 'a
   | `C of ([> `A of 'a ] as 'b) * ([> `A of 'a | `C of 'b * 'c ] as 'c) ] ->
  bool = <fun>
val occurs_foo : 'a -> [> `A of 'a ] -> bool = <fun>
val occurs_bar :
  'a -> ([> `A of 'a | `C of [> `A of 'a ] * 'b ] as 'b) -> bool = <fun>
# occurs 2 (`C ((`D (`B)), (`C (`A 3, (`D (`C (`A 4, `A 2)))))));;
- : bool = false

Basically specialising on the two types. There may be a way to coerce
them to not need it, but I'm not sure what it is.

Here are two other solutions:

# let rec occurs i x =
    let map = function
    | `A j -> `A j
    | `C (f,b) -> print_endline "C"; `C (f,b)
    | x -> `None
    in match map x with
    | `A j -> i = j
    | `None -> false
    | `C (f,b) -> (occurs i f) or (occurs i b);;
val occurs : 'a -> ([> `A of 'a | `C of 'b * 'b ] as 'b) -> bool = <fun>

--

# let occurs i x =
    let map = function
    | `A _ | `C (_,_) as x -> x | _ -> `None
    in
    let rec occurs = function
    | `A j -> i = j
    | `C (f,b) -> (occurs (map f)) or (occurs (map b))
    | `None -> false
    in occurs x;;
val occurs :
  'a ->
  [ `A of 'a
  | `C of
      ([> `A of 'a | `C of 'b * ([> `A of 'a | `C of 'b * 'c ] as 'c) ] as 'b) *

      'c
  | `None ] -> bool = <fun>

Pretty damn ugly! But it works... Perhaps someone more proficient with
variant types on the list can come up with a more reasonable solution
than my hack ;-)

Jonathan

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jacques Garrigue  
View profile
 More options Jun 29 2006, 12:33 am
Newsgroups: fa.caml
From: Jacques Garrigue <garri...@math.nagoya-u.ac.jp>
Date: Thu, 29 Jun 2006 04:33:02 UTC
Local: Thurs, Jun 29 2006 12:33 am
Subject: Re: [Caml-list] Question on Variant Types
On 6/29/06, Seth J. Fogarty <sfoga...@gmail.com> wrote:

As long as foo and bar are two subtypes of a common type, you can
still solve the problem by defining that type and using subtyping:

type foobar = [`A of int | `B | `C of foobar * foobar | `D of foobar]
let occurs_foo i x = occurs i (x : foo :> foobar)
let occurs_bar i x = occurs i (x : bar :> foobar)

Jacques Garrigue

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Another question on variant types and matching (was: Re: [Caml-list] Question on Variant Types)" by Richard Jones
Richard Jones  
View profile
 More options Jun 29 2006, 5:35 pm
Newsgroups: fa.caml
From: Richard Jones <r...@annexia.org>
Date: Thu, 29 Jun 2006 21:35:03 UTC
Local: Thurs, Jun 29 2006 5:35 pm
Subject: Another question on variant types and matching (was: Re: [Caml-list] Question on Variant Types)
I have another question on variant types which seems to be related to
this, but perhaps the opposite way round.  How can I get the code
below to work?  (It's simplified greatly from a real problem I'm
having).

Rich.

----------------------------------------------------------------------
type colour = [ `Red | `Green | `Blue ]
type colour' = [ colour | `Default ]
type instructions = Set_foreground of colour' | Set_background of colour'

let default_fg : colour = `Red
let default_bg : colour = `Green

let process_instructions =
  List.fold_left (
    fun (fg, bg) ->
      function
      | Set_foreground `Default ->
          let new_fg = default_fg in
          (new_fg, bg)
      | Set_foreground new_fg ->
          (new_fg, bg)
      | Set_background `Default ->
          let new_bg = default_bg in
          (fg, new_bg)
      | Set_background new_bg ->
          (fg, new_bg)
  )

let string_of_colour = function
  | `Red -> "red"
  | `Green -> "green"
  | `Blue -> "blue"

let () =
  let instrs =
    [ Set_foreground `Blue; Set_background `Red; Set_foreground `Default ] in
  let fg, bg = `Green, `Blue in
  let fg, bg = process_instructions (fg, bg) instrs in
  print_endline ("fg = " ^ string_of_colour fg);
  print_endline ("bg = " ^ string_of_colour bg)
----------------------------------------------------------------------

--
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jonathan Roewen  
View profile
 More options Jun 29 2006, 5:55 pm
Newsgroups: fa.caml
From: "Jonathan Roewen" <jonathan.roe...@gmail.com>
Date: Thu, 29 Jun 2006 21:55:23 UTC
Local: Thurs, Jun 29 2006 5:55 pm
Subject: Re: Another question on variant types and matching (was: Re: [Caml-list] Question on Variant Types)
Hi,

You just need some type constraints so it knows you're starting with a
colour pair, not a colour' pair:

let process_instructions (initial:colour * colour) =
 List.fold_left (
   fun (fg, bg) ->
     function
     | Set_foreground `Default ->
         let new_fg = default_fg in
         (new_fg, bg)
     | Set_foreground (#colour as new_fg) ->
         (new_fg, bg)
     | Set_background `Default ->
         let new_bg = default_bg in
         (fg, new_bg)
     | Set_background (#colour as new_bg) ->
         (fg, new_bg)
 ) initial

Jonathan

On 6/30/06, Richard Jones <r...@annexia.org> wrote:

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Jones  
View profile
 More options Jul 1 2006, 7:33 am
Newsgroups: fa.caml
From: Richard Jones <r...@annexia.org>
Date: Sat, 01 Jul 2006 11:33:29 UTC
Local: Sat, Jul 1 2006 7:33 am
Subject: Re: Another question on variant types and matching (was: Re: [Caml-list] Question on Variant Types)

On Fri, Jun 30, 2006 at 09:51:01AM +1200, Jonathan Roewen wrote:
>     | Set_foreground (#colour as new_fg) ->

Thanks - that's exactly the syntax I was looking for.

Rich.

--
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Question on Variant Types" by Jonathan Roewen
Jonathan Roewen  
View profile
 More options Jul 1 2006, 8:38 pm
Newsgroups: fa.caml
From: "Jonathan Roewen" <jonathan.roe...@gmail.com>
Date: Sun, 02 Jul 2006 00:38:58 UTC
Local: Sat, Jul 1 2006 8:38 pm
Subject: Re: [Caml-list] Question on Variant Types
And now I have my own question about variant types :-)

I seem to be running into the problem of not being able to coerce
polymorphic abstract types that use variants.

Eg:

type 'a t;;

type x = [ `Foo ];;
type y = [ `Bar | x ];;

let widen x = (x : x t :> y t);;

Gives:
Type x t is not a subtype of type y t
Type x = [ `Foo ] is not compatible with type y = [ `Bar | `Foo ]
The first variant type does not allow tag(s) `Bar

Yet the above approach works fine for non-abstract types.

Jonathan

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chris King  
View profile
 More options Jul 1 2006, 10:07 pm
Newsgroups: fa.caml
From: "Chris King" <colander...@gmail.com>
Date: Sun, 02 Jul 2006 02:07:12 UTC
Local: Sat, Jul 1 2006 10:07 pm
Subject: Re: [Caml-list] Question on Variant Types
On 7/1/06, Jonathan Roewen <jonathan.roe...@gmail.com> wrote:

> type 'a t;;

> type x = [ `Foo ];;
> type y = [ `Bar | x ];;

> let widen x = (x : x t :> y t);;

> Gives:
> Type x t is not a subtype of type y t
> Type x = [ `Foo ] is not compatible with type y = [ `Bar | `Foo ]
> The first variant type does not allow tag(s) `Bar

> Yet the above approach works fine for non-abstract types.

You need to explicitly specify the variance of 'a t:

type +'a t;;

This tells the type system that t is covariant with respect to 'a: if
x is a subtype of y, then x t is a subtype of y t.  Not all compound
types share this property (most notably, mutable structures are
invariant and function arguments are contravariant) so O'Caml must
assume all abstract types to be invariant unless it's told otherwise.

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2008 Google