Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parameterized class with map #3042

Closed
vicuna opened this issue Nov 19, 2001 · 1 comment
Closed

parameterized class with map #3042

vicuna opened this issue Nov 19, 2001 · 1 comment
Labels

Comments

@vicuna
Copy link

vicuna commented Nov 19, 2001

Original bug ID: 641
Reporter: administrator
Status: closed
Resolution: not a bug
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Full_Name: Dan McCabe
Version: 3.02
OS: WinXP
Submission from: 206.191.151.226 (206.191.151.226)

I define the following parameterized numeric class:
class ['p] numeric (vInit: 'p) =
object (self)
constraint 'p = < print: unit; map: ('p -> 'q) -> 'q >
val v = vInit
method value = v
method map (f: 'p -> 'q) = new numeric (v#map f)
method print = v#print
end
;;

This class includes a map function that converts the base type of the numeric
class into a different base type, not neccessarily the same as the original base
type, and creates a new numeric object with that different base type. An example
of such a function might be a function that projects 3D vectors into 2D vectors.
Ultimately, I want to create a bunch of virtual methods for addition,
subtraction, etc., but that it not the issue at hand.

When I enter this class definition into ocamlwin, it tells me that 'p is the
same as 'a and 'q is the same as 'a. I interpret this to mean that 'q must
always be the same as 'p.

I have attributed this result to the fact that I am not creating a "'q numeric"
in the map method. But when I try to add 'q, it complains of a syntax error.

I don't want to copy the record with {< >}, because it type should be different.
What I really want to do is create a 'q numeric as a result of the map, but I
can't figure out how to express that concept in a syntactically correct manner.

Sign me confused.

Cheers,
danm

@vicuna vicuna closed this as completed Nov 19, 2001
@vicuna
Copy link
Author

vicuna commented Nov 19, 2001

Comment author: administrator

From: danm@zen3d.com
Subject: parameterized class with map (#3042)

I define the following parameterized numeric class:
class ['p] numeric (vInit: 'p) =
object (self)
constraint 'p = < print: unit; map: ('p -> 'q) -> 'q >
val v = vInit
method value = v
method map (f: 'p -> 'q) = new numeric (v#map f)
method print = v#print
end
;;

This class includes a map function that converts the base type of
the numeric class into a different base type, not neccessarily the
same as the original base type, and creates a new numeric object
with that different base type. An example of such a function might
be a function that projects 3D vectors into 2D vectors. Ultimately,
I want to create a bunch of virtual methods for addition,
subtraction, etc., but that it not the issue at hand.

When I enter this class definition into ocamlwin, it tells me that 'p is the
same as 'a and 'q is the same as 'a. I interpret this to mean that 'q must
always be the same as 'p.

Yes, recursion is only monorphic. Parametric polymorphism only appears
after the class is completely checked. No bug here.

You have found a case of something impossible to do with Objective
Caml's class system. In fact there are two different problems. One is
that you want to use type 'q inside method map, without adding it as a
parameter to the class. For this you need polymorphic methods, which
should eventually make their way into the language.
But then you want this 'q to be a parameter to numeric, which is not
yet defined. For this we have no practical solution. The theory says
you need higher-order types, which is a bit far away.

Luckily, not being able to do something with a method does not mean
you cannot do it with a function.
You can define a function
let map_numeric f nm = new numeric (map_value f nm#value)
which shall do what you expect, with slightly less flexibility.

Note also that encapsulating values into classes is not necessarily a
good idea for this type of programming. IIRC, some project on
algebraic computation in Caml found that it was better to mix functors
and classes composed only of static methods to obtain maximal
flexibility.

Hope this helps,

Jacques Garrigue

@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant