# Help declaring some functions

**URL:** <https://discuss.ocaml.org/t/help-declaring-some-functions/1217>\
**Category:** Learning\
**Created:** [November 30, 2017, 8:11pm UTC](https://discuss.ocaml.org/t/help-declaring-some-functions/1217 "2017-11-30T20:11:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cliff\_Karlsson](https://avatars.discourse-cdn.com/v4/letter/c/34f0e0/32.png) [@Cliff\_Karlsson](https://discuss.ocaml.org/u/Cliff_Karlsson)\
**Post date:** [November 30, 2017, 8:11pm UTC](https://discuss.ocaml.org/t/help-declaring-some-functions/1217/1 "2017-11-30T20:11:18Z")

</div>

I just started learning OCaml but have a hard time understanding the “basics”. I have got some training examples where I am supposed to create the following functions but I have no clue of how to even start. Could anyone help me declare a few of them to see if I get the hang of it. We are not supposed to use any built-in library like List or similar.

I think I could figure out the cons, empty and length but the rest is a mystery to me.

val first: 'a my\_list -\> 'a /return the first element of a list.  
val last: 'a my\_list -\> 'a /return the last element of a list.  
val rest: 'a my\_list -\> 'a my\_list //return everything but the first element in a list.  
val cons: 'a -\> my\_list -\> 'a my\_list

val empty: 'a my\_list -\> bool  
val length: 'a my\_list -\> int

val map: ('a -\> 'b) -\> 'a my\_list -\> 'b my\_list /create the map function using the previously created functions  
val fold: ('b -\> 'a -\> 'a) -\> 'a -\> 'b my\_list -\> 'a  
val append: 'a my\_list -\> 'a my\_list -\> 'a my\_list

val as\_list 'a my\_list -\> 'a list  
val from\_list 'a list -\> 'a my\_list

---

<div class="post-metadata">

**Author:** ![cfcs](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cfcs/32/833_2.png) [@cfcs](https://discuss.ocaml.org/u/cfcs)\
**Post date:** [November 30, 2017, 9:46pm UTC](https://discuss.ocaml.org/t/help-declaring-some-functions/1217/2 "2017-11-30T21:46:35Z")

</div>

Most of these are covered in `OCaml from the very beginning` (and its exercises), which I can wholeheartedly recommend - it was the book that helped me get started.

You didn’t give us the type declaraction for your `my_list`, which makes it slightly tricky to help you write functions using it. I’ll assume it’s something like:

```ocaml
type 'a my_list = Nil | Node of 'a * 'a my_list

```

## It sounds like you may want to read up on “pattern matching.”

```ocaml
val first: 'a my_list -> 'a (* return the first element of a list.*)

```

```ocaml
let first = function
  | Nil -> failwith "throw an exception because the list has no elements"
  | Node (a, ignore_the_rest) -> a

```

The above will throw an exception if the list is empty. You might want to change your interface to be:

```ocaml
val first: 'a my_list -> 'a option
(** [first lst] returns [Some] the first element of [lst], or [None] if the list is empty. *)

```

```ocaml
let first = function
  | Nil -> None
  | Node ( a, _ ) -> Some a (* the _ is a wildcard which also means "throw this away *)

```

```ocaml
val last: 'a my_list -> 'a

```

```ocaml
let rec last = function
  | Nil -> None
  | Node (a, Nil) -> Some a
  | Node ( _ , remainder) -> last remainder (* call the function again with the next part *)

```

```ocaml
val rest: 'a my_list -> 'a my_list

```

For this one you can do pattern matching very similar to the `first` function.

```ocaml
val map: ('a -> 'b) -> 'a my_list -> 'b my_list

```

Here you’ll want to write a nested recursive function with an “accumulator”, a technique used to accumulate the result of your chain of recursive function calls. Your accumulator will be created using your `cons`, starting with a `Nil` list, adding the result of calling the `('a -> 'b)` function on each value taken from the `'a list` (which you can be split using your `first` and `last`).  
When you have made the new accumulator, the function can call itself again, until it is finished.

Note that the above will give you the reversed list of results, but you can get around that by calling your inner function again with a `(fun x -> x)` to get the “reverse of the reverse.” (== the correct order).

You’ll also need to know the length of the list and make sure you don’t call `first` or `last` on an empty list, since that will crash with an exception. This last bit can be avoided by using the `option` type as return value for those functions, as I outlined above.

`fold` is much the same, except that you set the “accumulator” (`'a`) to the result of the provided function applied with the value from the list and the old accumulator - instead of constructing a new list of results.

```ocaml
val append: 'a my_list -> 'a my_list -> 'a my_list

```

You can use `last` and `cons` here if you write a function that return “everything but the last”. That would be kind of like `map`, but with a special case for the last non-nil element.

```ocaml
val as_list 'a my_list -> 'a list

```

Here you can use fold\_left using `List.cons`.

```ocaml
 val from_list 'a list -> 'a my_list

```

Here you can also use pattern matching, using `::` to deconstruct the list while constructing your list. Then something like the inner function of your `map` function to reverse it.

Note that none of these proposed solutions are particularly performant, but they are probably the conceptually easiest.

---

<div class="post-metadata">

**Author:** ![Cliff\_Karlsson](https://avatars.discourse-cdn.com/v4/letter/c/34f0e0/32.png) [@Cliff\_Karlsson](https://discuss.ocaml.org/u/Cliff_Karlsson)\
**Post date:** [December 1, 2017, 11:55am UTC](https://discuss.ocaml.org/t/help-declaring-some-functions/1217/3 "2017-12-01T11:55:42Z")

</div>

> [@cfcs](#):
>
> OCaml from the very beginning

Thanks for the answer, the my\_list declaration looks like this if it makes any difference:

type 'a my\_list =  
| Empty  
| Cons of 'a list\_content  
and  
'a list\_content = { data: 'a; next: 'a my\_list }

---

<div class="post-metadata">

**Author:** ![kantian](https://avatars.discourse-cdn.com/v4/letter/k/4bbf92/32.png) [@kantian](https://discuss.ocaml.org/u/kantian)\
**Post date:** [December 1, 2017, 1:30pm UTC](https://discuss.ocaml.org/t/help-declaring-some-functions/1217/4 "2017-12-01T13:30:00Z")

</div>

That doesn’t change a lot, you just have to adapt your pattern matching. Example with first and last:

```ocaml
let first = function
  | Empty -> failwith "first: the list is empty"
  | Cons {data; _ } -> data

let rec last = function
  | Empty -> failwith "last: the list is empty"
  | Cons {data; next=Empty} -> data
  | Cons {next; _} -> last next

```
