haskell# Type-level tuple: how to avoid nesting in a type argument

Considering first-class-families library, I have a code:

```
import Fcf.Data.Common
import Fcf.Core
type T a b c = '(a, '(b, c))
data D a b t = D
{ a :: a
, b :: b
, c :: Eval (Fst t)
, d :: Eval (Fst (Eval (Snd t)))
, e :: Eval (Snd (Eval (Snd t)))
}
type MyT = T Int Int Bool
data C = C (D Int Int MyT)
```

with nesting only because no `Third`

(similarly to `Fst`

and `Snd`

). Is it possible to avoid this nesting in some more intelligent way? Maybe there is some operator allowing more flat "structure"? If no, what can be used instead of it?

Or from another point of view, maybe this code is not good:

```
Eval (Fst (Eval (Snd t)))
```

and there is a way to avoid the second `Eval`

?

Finally, I want `D`

taking type-level tuple of size > 2 and to pass it in a "flat" form if it's possible.

Solution

In case this is an X-Y problem, please note that you don't need the `first-class-families`

package to implement simple type-level functions. You can just use type families directly. So, the following will work fine:

```
{-# LANGUAGE TypeFamilies #-}
type family Fst triple where
Fst (a,b,c) = a
type family Snd triple where
Snd (a,b,c) = b
type family Thd triple where
Thd (a,b,c) = c
type T a b c = (a, b, c)
data D a b t = D
{ a :: a
, b :: b
, c :: Fst t
, d :: Snd t
, e :: Thd t
}
type MyT = T Int Int Bool
data C = C (D Int Int MyT)
```

Alternatively, you can define:

```
type T a b c = '(a, b, c)
```

and modify the type family definitions with ticks:

```
type family Fst triple where
Fst '(a,b,c) = a
-- etc. --
```

which will work too.

Two observations:

First, there's actually a big conceptual difference between the first "no ticks" version and the second "ticks" version. It's the type-level equivalent of working in a dynamically typed language ("no ticks") and a statically typed language ("ticks"), but if you don't have a compelling reason to use the "ticks" version, you should stick with the "no ticks" version, as it's more straightforward and perfectly idiomatic and -- like dynamically typed programming in general -- comes with some usability advantages, like allowing you to define:

```
type family Fst tuple where
Fst (a,b) = a
Fst (a,b,c) = a
Fst (a,b,c,d) = a
-- and so on --
```

and use the same `Fst`

function on different length tuples.

Second, the purpose of `first-class-families`

is to permit partially applied type-level functions. If you needed to pass `Fst`

to a `Map`

function, for example:

```
type Result = Map Fst '[(Double,Char,String),(Int,Double,Double)]
```

then the type family definitions in this answer wouldn't work because type families can only appear in type expressions fully applied to all their arguments.

If you don't need to use partially (or unapplied) type-level functions, then you don't need `first-class-families`

.

- couldn´t match type 'IO´ with ´[]` inside a do
- How does the Haskell compiler handle the 'where' statement?
- Why is the Factory pattern not needed in Haskell? And how are the needs that pattern addresses in OOP addressed in Haskell?
- Aeson : generics with default values
- Is there a Haskell compiler or preprocessor that uses strict evaluation?
- Python: Haskell-like . / $
- Make GHC deduce one type family constraint from another
- How to listen for window closing in X11 code?
- Can this generic DFS implementation in Haskell be used to detect cycles in an adjacency list?
- Do I need to understand how Haskell represents data to be able to write good Haskell programs?
- substitution in proofs with recursive formulas
- XMonad, spawn floating window right above focused window
- Example of using `linkOnly` from the async library
- How do I read what's in a binary tree in Haskell?
- When can a pointful function be refactored to be point free?
- Unable to compile first Haskell Programme in VSCode
- Does Haskell have something like gensym in Racket?
- Unknown error in Haskell that prevents a function from running
- Compiling Haskell (.hs) in windows to a exe
- How to build and modify source code locally of a package from Hackage using the `Haskell Stack`?
- How do I flip a juicy pixel image saved from glut
- Haskell at a user level
- Haskell WinGHC Running Program with Performance Statistics
- How can I check file permissions of a Linux file using Haskell?
- Searching for Reverse Dependencies on Hackage
- Unsafe coerce and more efficient Agda code (-ftrust-me-im-agda)
- Pattern match where type has constructors
- Is Haskell a strongly typed programming language?
- How do I overload a certain operator in haskell to take different types on either side?
- How can I use contradictory evidence?