# Ref list of functions

**URL:** <https://discuss.ocaml.org/t/ref-list-of-functions/1860>\
**Category:** Learning\
**Created:** [April 14, 2018, 6:41pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860 "2018-04-14T18:41:10Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![sc0102](https://avatars.discourse-cdn.com/v4/letter/s/ecd19e/32.png) [@sc0102](https://discuss.ocaml.org/u/sc0102)\
**Post date:** [April 14, 2018, 6:41pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/1 "2018-04-14T18:41:10Z")

</div>

Why compiler throws an error for ref list of tuples of function and string?

let attrList:((('a -\> bool) \* 'c) list) ref = ref []

Error:The type of this expression, ((’\_a -\> bool) \* '\_c) list Batteries.ref,  
contains type variables that cannot be generalized

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [April 14, 2018, 7:01pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/2 "2018-04-14T19:01:07Z")

</div>

The problem is that the type that you wrote is not precise enough: the type of a mutable field or a reference must be a concrete type with no free type variables in a given compilation unit. Indeed since a mutable value can be wrote to and read from, it must always give a consistent view of its content. You can look at the [reference manual](http://caml.inria.fr/pub/docs/manual-ocaml/polymorphism.html#sec51) for a more detailed explanation.

---

<div class="post-metadata">

**Author:** ![sc0102](https://avatars.discourse-cdn.com/v4/letter/s/ecd19e/32.png) [@sc0102](https://discuss.ocaml.org/u/sc0102)\
**Post date:** [April 14, 2018, 8:29pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/3 "2018-04-14T20:29:14Z")

</div>

How should I make it precise?

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [April 14, 2018, 8:57pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/4 "2018-04-14T20:57:24Z")

</div>

By writing the type of the elements of the list.

And you cannot have a non-empty list with an element of type `'c` for all type `'c`, because this type has no inhabitant. In other words, a real value cannot be simultaneously an `int` and a `float` and a `string` and etc.

Similarly, without playing tricks, the only functions with type `'a -> bool`, for any `'a`, are `fun _ -> true` and `fun _ -> false`.

---

<div class="post-metadata">

**Author:** ![sc0102](https://avatars.discourse-cdn.com/v4/letter/s/ecd19e/32.png) [@sc0102](https://discuss.ocaml.org/u/sc0102)\
**Post date:** [April 16, 2018, 3:06pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/5 "2018-04-16T15:06:09Z")

</div>

I tried to make precise type annotations using two methods -

I tried both these methods -  
By giving an actual example of the list

let attrList = ref [((fun (l,n) -\> n \> 0), “n \> 0”)]

I get this error for this -

The type of this expression,  
((’\_weak1 \* int -\> bool) \* string) list Batteries.ref,  
contains type variables that cannot be generalized  
makefile:4: recipe for target 'dep-only’ failed

By giving precise type annotations -

let attrList:((((fun (\_) -\> bool) \* string) list) ref) = ref []

I get syntax error for this one -

File “pie.ml”, line 11, characters 17-20:  
Error: Syntax error  
makefile:4: recipe for target ‘dep-only’ failed  
make: \*\*\* [dep-only] Error 2

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [April 16, 2018, 3:26pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/6 "2018-04-16T15:26:07Z")

</div>

> [@sc0102](#):
>
> let attrList = ref [((fun (l,n) -\> n \> 0), “n \> 0”)]

What is the type of the first argument (`l`) ?

---

<div class="post-metadata">

**Author:** ![sc0102](https://avatars.discourse-cdn.com/v4/letter/s/ecd19e/32.png) [@sc0102](https://discuss.ocaml.org/u/sc0102)\
**Post date:** [April 16, 2018, 3:28pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/7 "2018-04-16T15:28:05Z")

</div>

int, but the thing is the number of arguments can change and they can be list or int.

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [April 16, 2018, 3:36pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/8 "2018-04-16T15:36:12Z")

</div>

List are homogeneous in OCaml, the type of elements cannot change ( and even with heterogeneous list, a reference containing such list will have a constant type itself).

The correct syntax for type annotation is:

```auto
let attrList: ( ( int -> int -> bool ) * string) list ref = ref []

```

If you want to have varying number of argument, that can either int of list of `int`s, you should use a variant

```auto
type arg = List of int list | Single of int

```

and makes the stored functions takes a list of `arg`s

```auto
let attrList: ( ( arg list -> bool) * string) list ref = ref []

```

---

<div class="post-metadata">

**Author:** ![sc0102](https://avatars.discourse-cdn.com/v4/letter/s/ecd19e/32.png) [@sc0102](https://discuss.ocaml.org/u/sc0102)\
**Post date:** [April 17, 2018, 10:16pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/9 "2018-04-17T22:16:54Z")

</div>

Awesome, thank you so much.

---

<div class="post-metadata">

**Author:** ![egoholic](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/egoholic/32/574_2.png) [@egoholic](https://discuss.ocaml.org/u/egoholic)\
**Post date:** [April 18, 2018, 9:35am UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/10 "2018-04-18T09:35:11Z")

</div>

I suppose you need to learn this document [https://caml.inria.fr/pub/docs/manual-ocaml/polymorphism.html](https://caml.inria.fr/pub/docs/manual-ocaml/polymorphism.html)

---

<div class="post-metadata">

**Author:** ![sc0102](https://avatars.discourse-cdn.com/v4/letter/s/ecd19e/32.png) [@sc0102](https://discuss.ocaml.org/u/sc0102)\
**Post date:** [April 18, 2018, 4:05pm UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/11 "2018-04-18T16:05:43Z")

</div>

So I have -

type arg = List of int list | Single of int  
let attrList: ( ( arg list -\> bool) \* string) list ref = ref []

Now I want to append items to attrList using pattern matching -

let rec createAttributeList features =  
match features with  
[] -\> attrList := attrList.contents  
|(a,b)::tl -\> if (true) then (attrList := (a,b)::attrList.contents) else (createAttributeList tl)

here ‘a’ can be a function with a single argument or two arguments - it could be int or list of int.

How can I accomplish this? Basically, I am adding items from the local list to global list. both lists have same format.

---

<div class="post-metadata">

**Author:** ![octachron](https://avatars.discourse-cdn.com/v4/letter/o/49beb7/32.png) [@octachron](https://discuss.ocaml.org/u/octachron)\
**Post date:** [April 19, 2018, 8:58am UTC](https://discuss.ocaml.org/t/ref-list-of-functions/1860/12 "2018-04-19T08:58:59Z")

</div>

You should have a look at `List.iter`, `List.filter`, and `List.map` . Moreover, rather than updating the global reference at each step, you should write a function that append together two lists and then uses this function to update the global reference. (and are you sure that you need such global state?). Finally, you should specify what you are trying to do and what is not working rather than what mechanism you are trying to use.
