| Jon Harrop 2007-04-06, 7:06 pm |
| John Sasso wrote:
> I've been spending hours on this and tried many different variations in
> defining matrixidx, but no-go. I am very and do not know what
> the problem is, or even how to fix it. Thanks!
There are many problems here. Firstly, I'm going to assume that you want a
type that unifies arbitrary-dimensionality arrays into a single type.
ML already has multidimensional arrays but their dimensionality must be
resolved at compile time.
Also, I'm going to use OCaml and not SML.
Your sum type contained only one constructor, which makes it superfluous:
# type 'a array = Array of (int * 'a list)
to avoid confusion with the built-in "array" type, I'm going to call the new
type "t". If you remove the superfluous constructor you get:
# type 'a t = int * 'a list;;
However, this is also pointless because this type can be completely inferred
and, therefore, there is no need to declare it explicitly. Regardless, you
can then write examples like:
# let v : 'a t = 3, [1; 2; 3];;
val v : int t = (3, [1; 2; 3])
# let m : 'a t t = 3, [3, [1; 2; 3];
3, [4; 5; 6];
3, [7; 8; 9]];;
val m : int t t = (3, [(3, [1; 2; 3]); (3, [4; 5; 6]); (3, [7; 8; 9])])
Note that "int t t" is a kind of "'a t".
Now you can write your index function (I'll call it "get", like Array.get)
as:
# let rec get = function
| [1], (_, h::_) -> h
| [i], (d, _::t) -> get([([i], (d, t))
| 1::i, (d, h::_) -> get(i(i, (d, h))
| i::is, (d, _::t) -> get (is, (d, t))
| _ -> invalid_arg "get";;
val get : int list * ('a * ('b list as 'b)) -> 'b = <fun>
Note that this does not use the declared type "'a t" but it does rely upon
OCaml's recursive types.
This also highlights the fact that your "outermost dimensionality"
variable "d" is largely pointless too.
I suspect you really wanted to define a type that allows nested arrays.
Perhaps something like this would be better:
# type 'a t = Elt of 'a | Array of 'a t array;;
type 'a t = Elt of 'a | Array of 'a t array
Define some constructors:
# let aux f a = Array(Array.map f a);;
val aux : ('a -> 'b t) -> 'a array -> 'b t = <fun>
# let array1 a = aux (fun x -> Elt x) a;;
val array1 : 'a array -> 'a t = <fun>
# let array2 a = aux array1 a;;
val array2 : 'a array array -> 'a t = <fun>
Example nested arrays:
# let v = array1 [|1; 2; 3|];;
val v : int t = Array [|Elt 1; Elt 2; Elt 3|]
# let m = array2 [|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|];;
val m : int t =
Array
[|Array [|Elt 1; Elt 2; Elt 3|]; Array [|Elt 4; Elt 5; Elt 6|];
Array [|Elt 7; Elt 8; Elt 9|]|]
Element extraction:
# let rec get is x = match is, x with
| [], Elt x -> x
| i::is, Array a -> get is a.(i)
| _ -> invalid_arg "get";;
val get : int list -> 'a t -> 'a = <fun>
For example:
# get [1; 2] m;;
- : int = 6
PS: comp.lang.ml is basically dead so I'm forwarding this to c.l.functional.
--
Dr Jon D Harrop, Flying Frog Consultancy
OCaml for Scientists
http://www.ffconsultancy.com/produc...dex.html?usenet
|