# MapRes and Exotic data

So far only HKD and tuples have been used in queries and results, but there are far more types you can use here. In theory, any type that has instances of `ApplyKC`

and `TraverseKC`

can be used in queries.

However, Scala's type inference does not work well enough if the destination type does not have the kind `F[_[_]]`

. This excludes types, or other non-simple types. To solve this problem, DataPrism introduces the type `MapRes[F, R] { type K[A[_]] }`

. `MapRes`

serves as an evidence that the type R incorporates the type F on its elements, and that the type `K[F] = R`

. For example `MapRes[DbValue, (DbValue[Boolean], DbValue[Int])]`

says that in the type `(DbValue[Boolean], DbValue[Int])`

, the values are wrapped in `DbValue`

. It also indicates that the type `K[F[_]] = (F[Boolean], F[Int])`

.

`MapRes`

also contains functions to convert to and from `K[F]`

, in addition to `ApplyKC`

and `TraverseKC`

instances.

Here is a list of all the types `MapRes`

will handle. The Aux type of `MapRes`

will be used to show all the types of `MapRes`

. Where a type could be anything, a type lambda will be used to show that the types could be something else.

`[F[_[_]], G[_]] =>> MapRes.Aux[F[G], G, F]`

MapRes handles higher kinded data, or other types with the kind `F[_[_]]`

.

`[F[_], T <: NonEmptyTuple]`

=>> MapRes.Aux[F, T, [F0[_]] =>> Tuple.Map[Tuple.InverseMap[T, F], F0]

MapRes handles non-empty tuples, as long as all the elements are mapped by the required type, for example `DbValue`

.

`[F[_], A] =>> MapRes.Aux[F, F[A], [F0[_]] =>> F0[A]`

MapRes handles single values of type `F[A]`

.

## Tuple recursion

If all the elements of a tuple have instances of `MapRes`

, so does the tuple itself

## Lifting Apply and Traverse to MapRes

If the `MapRes`

instance `[F[_], V, MRK[_[_]]] =>> MapRes.Aux[F, V, MRK]`

exists, and `G[_]`

is a type with instances `Apply[G]`

and `Traverse[G]`

, then there is also a `MapRes`

of type `[F[_], G[_], V, MRK[_[_]]] =>> MapRes.Aux[F, G[V], [F0[_]] =>> G[MRK[F0]]`

What this practically mean is that `Option[DbValue[Int]]`

could for example be a valid type, and will follow the semantics of the `Apply`

and `Traverse`

instances for `G`

.

Think of this as a sort of metaprogramming for the generated SQL.

Derived instances of `ApplyKC`

and `TraverseKC`

also supports the same principle.

### Beware Lists

Beware of using `List`

in the above manner. `List`

will operate in accordance to it's `Apply`

instance. For example, `map2`

on two lists of 3 elements each will produce an element of 9 elements, combining the cross product of the two lists. If you want zipping behavior, use `ZipList`

instead.