# Data.Profunctor.Strong

- Package
- purescript-profunctor
- Repository
- purescript/purescript-profunctor

### #Strong Source

`class Strong :: (Type -> Type -> Type) -> Constraint`

`class (Profunctor p) <= Strong p where`

The `Strong`

class extends `Profunctor`

with combinators for working with
product types.

`first`

and `second`

lift values in a `Profunctor`

to act on the first and
second components of a `Tuple`

, respectively.

Another way to think about Strong is to piggyback on the intuition of inputs and outputs. Rewriting the type signature in this light then yields:

```
first :: forall input output a. p input output -> p (Tuple input a) (Tuple output a)
second :: forall input output a. p input output -> p (Tuple a input) (Tuple a output)
```

If we specialize the profunctor p to the function arrow, we get the following type signatures, which may look a bit more familiar:

```
first :: forall input output a. (input -> output) -> (Tuple input a) -> (Tuple output a)
second :: forall input output a. (input -> output) -> (Tuple a input) -> (Tuple a output)
```

So, when the `profunctor`

is `Function`

application, `first`

essentially applies your function
to the first element of a `Tuple`

, and `second`

applies it to the second element (same as `map`

would do).

#### Members

`first :: forall a b c. p a b -> p (Tuple a c) (Tuple b c)`

`second :: forall a b c. p b c -> p (Tuple a b) (Tuple a c)`

#### Instances

### #splitStrong Source

`splitStrong :: forall p a b c d. Category p => Strong p => p a b -> p c d -> p (Tuple a c) (Tuple b d)`

Compose a value acting on a `Tuple`

from two values, each acting on one of
the components of the `Tuple`

.

Specializing `(***)`

to function application would look like this:

```
(***) :: forall a b c d. (a -> b) -> (c -> d) -> (Tuple a c) -> (Tuple b d)
```

We take two functions, `f`

and `g`

, and we transform them into a single function which
takes a `Tuple`

and maps `f`

over the first element and `g`

over the second. Just like `bi-map`

would do for the `bi-functor`

instance of `Tuple`

.

### #(***) Source

Operator alias for Data.Profunctor.Strong.splitStrong *(right-associative / precedence 3)*

### #fanout Source

`fanout :: forall p a b c. Category p => Strong p => p a b -> p a c -> p a (Tuple b c)`

Compose a value which introduces a `Tuple`

from two values, each introducing
one side of the `Tuple`

.

This combinator is useful when assembling values from smaller components, because it provides a way to support two different types of output.

Specializing `(&&&)`

to function application would look like this:

```
(&&&) :: forall a b c. (a -> b) -> (a -> c) -> (a -> (Tuple b c))
```

We take two functions, `f`

and `g`

, with the same parameter type and we transform them into a
single function which takes one parameter and returns a `Tuple`

of the results of running
`f`

and `g`

on the parameter, respectively. This allows us to run two parallel computations
on the same input and return both results in a `Tuple`

.