How do I create my own data type with Arrow

The steps to create data types in Arrow that conform to Type classes like Functor and therefore provide methods like map is outlined here:

  1. Enable higher kinded type emulation. https://arrow-kt.io/docs/patterns/glossary/#higher-kinds

  2. Implement the type class instance https://arrow-kt.io/docs/patterns/glossary/#using-higher-kinds-with-typeclasses

In the two links above there is an example that uses ListK wrapping the std lib List. What the documentation example does not mention is that in order to expand the extensions which Functor would add over ListK including map, lift, etc as defined in the Functor interface it requires kapt and arrow meta.

kapt    "io.arrow-kt:arrow-meta:$arrow_version"

Arrow meta is in charge of expanding Higher Kinds and Extensions for type class instances. One limitation in the current expansion is that if you plan to use both @higherkind and @extension in the same module it won't work due to the order in which kapt processes. For that you would need to have data types in one module and extensions in a different one. This is actually good practice and what we follow in Arrow because it allows user to import data types a la carte when they don't want the extensions.