# Type Inference by Example, Part 2

Continuing where we left off in part 1, let’s look at a more advanced example that uses local variables and type constructors:

`function range(from, to) {    let numbers = [];    for(let i = from; i <= to; i++) {        numbers[i - from] = i;    }    return numbers;}`

As in the previous installment, we add in fresh type variables:

`function range(from : \$1, to : \$2) : \$3 {    let numbers : \$4 = [];    for(let i : \$5 = from; i <= to; i++) {        numbers[i - from] = i;    }    return numbers;}`

Now, on the very first line, we encounter the empty array:

`let numbers : \$4 = [];`

We know that it should be an Array<… something …>, but what is something? Why, a fresh type variable of course! So for this line, we get the following constraint:

`\$4 == Array<\$6>`

The next line starts the for loop:

`for(let i : \$5 = from; i <= to; i++) {`

Wow, three statements in one line! Assuming that `++ : Int => Int`, this gives us three constraints:

`\$5 == \$1\$5 == \$2\$5 == Int`

The for loop body assigns a value to an index in `numbers`:

`numbers[i - from] = i;`

This tells us two things: Numbers must be an array, and its element type must be the same as the type of `i`.

`\$4 == Array<\$5>`

From the same line, assuming `— : (Int, Int) => Int` we also constrain the types of `i` and `from` to be integers:

`\$5 == Int\$1 == Int`

And finally, from the return statement, we constrain the return type to be the same as the type of `number`:

`\$3 == \$4`

Now that we have generated all the constraints, let’s consider them all together:

`\$4 == Array<\$6>\$5 == \$1\$5 == \$2\$5 == Int\$4 == Array<\$5>\$5 == Int\$1 == Int\$3 == \$4`

Again, unification finds a substitution that solve the above system of equations, but let’s first consider the two constraints involving `Array`. Because `\$4` is on the other side of both equations, we can simplify that to `Array<\$6> == Array<\$5>`. Since both use a type constructor named `Array`, we check the generic arguments against each other by generating the constraint `\$6 == \$5`. And we already have another constraint that `\$5 == Int`. The resulting substitution is thus:

`\$1 := Int\$2 := Int\$3 := Array<Int>\$4 := Array<Int>\$5 := Int\$6 := Int`

Applying that to our syntax tree, we get:

`function range(from : Int, to : Int) : Array<Int> {    let numbers : Array<Int> = [];    for(let i : Int = from; i <= to; i++) {        numbers[i - from] = i;    }    return numbers;}`

And we’re done.

Stay tuned for part 3, where we’re going to look generic function calls.

--

--

--

## More from Joakim Ahnfelt-Rønne

MSc Computer Science, working with functional programming in the industry — github.com/ahnfelt

Love podcasts or audiobooks? Learn on the go with our new app.

## Makers Academy W4 D2: Databasics ## Introducing Kudos ## Configuring Docker, and configuring a webserver on the Docker container using Ansible ## How to Build an NFC-Powered Door Lock with a Raspberry Pi — Switched On Network ## We hate queues in shops, but we love them in IT ## Understanding Gousto Architecture: The Theory ## Characteristics of a Great Scrum Master ## Joakim Ahnfelt-Rønne

MSc Computer Science, working with functional programming in the industry — github.com/ahnfelt

## The Arbitrary Substitution Principle ## Everything You Need to Know about Angular ## Timed Automata and Application ## Complexity classes in Algorithms
{"ft_lang_label":"__label__en","ft_lang_prob":0.78458154,"math_prob":0.9649755,"size":2417,"snap":"2022-27-2022-33","text_gpt3_token_len":678,"char_repetition_ratio":0.13758807,"word_repetition_ratio":0.15448852,"special_character_ratio":0.3388498,"punctuation_ratio":0.16893204,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9882775,"pos_list":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],"im_url_duplicate_count":[null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,3,null,1,null,2,null,1,null,1,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-06-28T11:34:19Z\",\"WARC-Record-ID\":\"<urn:uuid:970bb7ba-05fa-47b3-be15-732634acb435>\",\"Content-Length\":\"145798\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:83bbcf49-5fe7-411e-9f2c-f0bb9ae8e9e7>\",\"WARC-Concurrent-To\":\"<urn:uuid:9fe9f007-dc75-4a6b-a41a-d05c3b3b0599>\",\"WARC-IP-Address\":\"162.159.153.4\",\"WARC-Target-URI\":\"https://ahnfelt.medium.com/type-inference-by-example-part-2-46933a75a116\",\"WARC-Payload-Digest\":\"sha1:NSJNXND2JILNGWBSL64BZ4B2QRNKERDA\",\"WARC-Block-Digest\":\"sha1:SMHIS3ZQDYQQHSQS2AZGGE5ML5LXHTPK\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-27/CC-MAIN-2022-27_segments_1656103516990.28_warc_CC-MAIN-20220628111602-20220628141602-00425.warc.gz\"}"}