emi
emi

Reputation: 2950

OCaml function type definition

I want to write a function of type

int -> 'a -> (int, int) slowa list

I was wondering would I necessarily need to defing first a type slowa

If so, this is how I defined my "slowa"

    type slowa = 
    (_,_)
    |('a, 'b) of int * int
;;

Where slowa is of type (int, int) But I'm not sure how if I am thinking right. I'd appreciate some help. I'm new to this :)

EDIT: So now I went ahead to try this:

type ('b, 'a) slowa = int * 'b
let c = 3, 5;;
let d = 1, 3;;

let rec add k v d =
    match d with
    | [] -> [(k,  v)]
    | (k', v')::t ->
        if k = k'
        then (k, v) :: t
        else (k', v') :: add k v t
        ;;

but I want it the type of the function add to be like this type: int -> 'a -> (int, int) slowa list

It would be easier if I wanted to return just list but now the return type is int -> 'a -> (int, int) slowa list which gets confusing... :/ I stand to be correct on the number/type of parameters.

Upvotes: 0

Views: 569

Answers (1)

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66823

If you just want a type that's a synonym for int * int (pairs of ints), you can define it like this:

type slowa = int * int

In this case, the name is just a synonym. You could always replace uses of the name by the definition. So you don't actually need to make the definition (it's good for documentation).

If you want to define a new type, you need to define a constructor for it:

type myslowa = Slow of int * int

This defines a new type. Values of the type look like Slow (3, 4). These values have a type different from all others; i.e., they are not interchangeable with pairs of ints.

If you want to define a parameterized type, you need to include the parameter(s) in your definition:

type ('a, 'b) pslowa = 'a * 'b

Since there's no new constructor, this is also just a synonym. But it's a synonym for an infinite set of types. In particular, it's a synonym for pairs of any two types.

If you want to define a new, parameterized type, you need to have both parameters and a constructor:

type ('a, 'b) mypslowa = Slow of 'a * 'b

This combines the properties; i.e., it is a new type that represents pairs of any two types.

I hope this helps; one of these might be close to what you're looking for.

Update

With your new definition of slowa, the type (int, int) slowa is identical to the type int * int. When the toplevel shows you the type of something, it has to choose among all the ways of representing the type. I think what you're saying is that the toplevel chooses to use int * int rather than (int, int) slowa. It's best not to get too hung up on this (IMHO). The one thing you might try is to annotate your types:

type ('b, 'a) slowa = int * 'b
let c = 3, 5;;
let d = 1, 3;;

let rec add k v (d: ('a, 'b) slowa list) : ('a, 'b) slowa list =
    match d with
    | [] -> [(k,  v)]
    | (k', v')::t ->
        if k = k'
        then (k, v) :: t
        else (k', v') :: add k v t
        ;;

(Your definition of slowa looks a little strange, since you're not using the 'a parameter for anything.)

Upvotes: 3

Related Questions