/Я language (β)/Articles/Components of natural transformations/

Source code for snippets ⋅ Twitter discussion ⋅ Reddit discussion ⋅ Linkedin discussion ⋅ Facebook discussion

This is an extension of Transformations, functors, categories article with more practical use cases.

We've seen this trivial component of natural transformation used as an example:

> Arrow `har` derive `ha` First : List `C'AR__` Maybe

According to First behaviour we will get some value only if List is not empty:

> Null `ho'vt` Unit `ryo` derive @ Maybe @ List `ha` First = Empty `har` Unit
> Only `ho'ut'st` A `_ryo` derive @ Maybe @ List `ha` First = Exist `har'st` A

If the same List would be non empty we could get a Front item at any time:

> Arrow `har` derive `ha` Front : Nonempty List `C'AR__` Alone

Despite the fact these are Arrow components between distinct functors they look alike:

> A `has` B `ryo` derive `ha` First = Exist `har'st` A
> A `has` B `ryo` derive `ha` Front = Alone `har'st` A

We also have components with same labels but in another category called Scope:

> Scope `har` within `ha` First : List `C'AT__` Maybe
> Scope `har` within `ha` Front : Nonempty List `C'AT__` Alone

Since Scope is a subtype of Arrow - components behaviour should be aligned with the latter accordingly:

> A `has` B `ryo` this `ha` within `ha` First = Exist `har'st` A
> A `has` B `ryo` this `ha` within `ha` Front = Alone `har'st` A

But additional power that Scope brings to Arrow is to update values without affecting the rest of datastructures:

> A `has` B `ryo` that `ha` within `ha` First `har__` Empty `har` Unit = B `ryo` Enter @ List
> A `has` B `ryo` that `ha` within `ha` First `har__` Exist `har_'st` O = O `has` B `ryo` Enter @ List
> A `has` B `ryo` that `ha` within `ha` Front `har__` Alone `har_'st` O = O `has` B `ryo` Enter @ Nonempty List

For both First and Front behaviour (they do point to a head item) we have their counterpart - Stock that points to tail items:

> Scope `har` within `ha` Stock : List `C'AT__` List
> Scope `har` within `ha` Stock : Nonempty List `C'AT__` List

Challenge: why in both cases we point to a List? Why couldn't we point to a Nonempty List?

> A `has_` B `has` C `ryo` this `ha` within `ha` Stock = B `has` C `ryo` Enter
> A `has` B `ryo` that `ha` within `ha` Stock `har__` O `has` E `ryo` Enter = A `has_` O `has` E `_ryo` Enter

So far we have seen Arrow and Scope component, but we also have Event one:

> Event `har` happen `ha` Sever `ha` First : List `C'TR__` Maybe

Its purpose is to separate First item and Stock ones i.e. pop operation:

> A `has_` B `has` C `ryo` this `ha` happen `ha` First = Exist `har'st` A
> A `has_` B `has` C `ryo` that `ha` happen `ha` First = B `has` C `ryo` Enter

Okay, so it was an overview of some available components for List and its variation - Nonempty List.

As you may noticed already, we can co-represent both of them with Sum of Units infinitely:

> A `ryo` Enter @ List
> A `ryo` Enter @ Nonempty List
> A `has` B `ryo` Enter @ List
> A `has` B `ryo` Enter @ Nonempty List
> A `has_` B `has` C `ryo` Enter @ List
> A `has_` B `has` C `ryo` Enter @ Nonempty List

There is another List variation called Scrolling List and we also can co-represent it:

> A `has` B `has___` C `has___` D `has` E `__ryo` Enter @ Scrolling List

Natural transformation associated with underlying functors could tell us a lot about purpose of such a datastructure:

> Event `har` happen `ha` Shift `ha` Forth : Scrolling List `C'TR__` Maybe
> Event `har` happen `ha` Shift `ha` Aback : Scrolling List `C'TR__` Maybe
> Scope `har` within `ha` Shaft : Scrolling List `C'AT__` Shafted List
> Scope `har` within `ha` Front : Scrolling List `C'AT__` Alone

Let's try out Event components - they let us Shift Front item Aback and Forth:

> A `has` B `has_` C `has_` D `has` E `ryo` that `ha` happen `ha` Shift `ha` Forth = A `has` B `has` C `has_` D `has_` E `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` that `ha` happen `ha` Shift `ha` Aback = A `has_` B `has_` C `has` D `has` E `ryo` Enter

Many of you already recognised List Zipper here since we can bidirectionally traverse a List with O(n).

It's might be not convenient to look at the result as a whole datastructures, we can Scope within updated Front item instead:

> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Front = Alone `har'st` C
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Front `ha` that `ha` happen `ha` Shift `ha` Forth = Alone `har'st` D
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Front `ha` that `ha` happen `ha` Shift `ha` Aback = Alone `har'st` B

But can we access adjacent items without modifying it's Front item? Scope components related to Scrolling List again:

> Scope `har` within `ha` Front : Scrolling List `C'TR__` Alone
> Scope `har` within `ha` Shaft : Scrolling List `C'TR__` Shafted List

So in co-representation of Scrolling List we put Front item in the middle of Shafted List so that we can visualise continuity:

> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Front = C `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Shaft = A `has` B `has_` D `has` E `ryo` Enter

... and Shafted List is essentially a Product of Lists, each of them we can access using according components:

> Scope `har` within `ha` Forth : Shafted List `C'AT__` List
> Scope `har` within `ha` Aback : Shafted List `C'AT__` List

Challenge: why in case of Aback the resulted List is reversed? It's related to ability to Shift for O(n).

> A `has` B `has_` D `has` E `ryo` this `ha` within `ha` Forth = D `has` E `ryo` Enter
> A `has` B `has_` D `has` E `ryo` this `ha` within `ha` Aback = B `has` A `ryo` Enter

... and, as if was stated in the beginning, List itself has a component that points to a First item. What we have:

> Scope `har` within `ha` Shaft : Scrolling List `C'AT__` Shafted List
> Scope `har` within `ha` Forth : Shafted List `C'AT__` List
> Scope `har` within `ha` First : List `C'AT__` Maybe

Now look closely at type declarations above - having an itch for composing those? Just place these labels together:

> Scope `har` within `ha` Forth `ha` Shaft : Scrolling List `C'AT__` List
> Scope `har` within `ha` First `ha` Forth : Shafted List `C'AT__` Maybe
> Scope `har` within `ha` First `ha` Forth `ha` Shaft : Scrolling List `C'AT__` Maybe

What you just saw corresponds to vertical composition of natural transformations. See it in action:

> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Front = C `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Shaft = A `has` B `has_` D `has` E `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Forth `ha` Shaft = D `has` E `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` Aback `ha` Shaft = A `has` B `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` First `ha` Forth `ha` Shaft = D `ryo` Enter
> A `has` B `has_` C `has_` D `has` E `ryo` this `ha` within `ha` First `ha` Aback `ha` Shaft = B `ryo` Enter