... | @@ -367,3 +367,35 @@ class(Bifunctor t,Bifoldable t)=>Bitraversable t where |
... | @@ -367,3 +367,35 @@ class(Bifunctor t,Bifoldable t)=>Bitraversable t where |
|
|
|
|
|
|
|
|
|
Each class contains further methods, but they can be defined in terms of the above ones. Therefore, we need only derive implementations for them. This also mirrors how the algorithms currently work in the one-parameter cases, as they only implement `fmap`, `foldMap`, `foldr`, and `traverse`.
|
|
Each class contains further methods, but they can be defined in terms of the above ones. Therefore, we need only derive implementations for them. This also mirrors how the algorithms currently work in the one-parameter cases, as they only implement `fmap`, `foldMap`, `foldr`, and `traverse`.
|
|
|
|
|
|
|
|
### Algorithms
|
|
|
|
|
|
|
|
|
|
|
|
A pseudo-code algorithm for generating a `bimap` implementation is:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
We write the derivation of bimap code over the last two type variables
|
|
|
|
'a and 'b, for the given type 'c, as ($bimap 'a 'b 'c). We refer bimap's
|
|
|
|
first and second map functions as f and g, respectively.
|
|
|
|
|
|
|
|
$(bimap 'a 'b 'c) = \x -> x -- when c does not contain a or b
|
|
|
|
$(bimap 'a 'b 'a) = f
|
|
|
|
$(bimap 'a 'b 'b) = g
|
|
|
|
$(bimap 'a 'b '(c1,c2)) = \x -> case x of (x1,x2) -> ($(bimap 'a 'b 'c1) x1, $(bimap 'a 'b 'c2) x2)
|
|
|
|
$(bimap 'a 'b '(T c1 c2)) = bimap $(bimap 'a 'b 'c1) $(bimap 'a 'b 'c2) -- when a and b only occur in the last two parameters, c1 and c2
|
|
|
|
$(bimap 'a 'b '(c -> d)) = \x e -> $(bimap 'a 'b 'd) (x ($(cobimap 'a 'b 'c) e))
|
|
|
|
|
|
|
|
For functions, the type parameters, 'a and 'b, can occur in contravariant positions,
|
|
|
|
which means we need to derive a function like:
|
|
|
|
|
|
|
|
cobimap :: (a -> b) -> (c -> d) -> (f b d -> f a c)
|
|
|
|
|
|
|
|
This is pretty much the same as $bimap, only without the $(cobimap 'a 'b 'a) and $(cobimap 'a 'b 'b) cases:
|
|
|
|
|
|
|
|
$(cobimap 'a 'b 'c) = \x -> x -- when c does not contain a or b
|
|
|
|
$(cobimap 'a 'b 'a) = error "type variable in contravariant position"
|
|
|
|
$(cobimap 'a 'b 'b) = error "type variable in contravariant position"
|
|
|
|
$(cobimap 'a 'b '(c1,c2)) = \x -> case x of (x1,x2) -> ($(cobimap 'a 'b 'c1) x1, $(cobimap 'a 'b 'c2) x2)
|
|
|
|
$(cobimap 'a 'b '(T c1 c2)) = bimap $(cobimap 'a 'b 'c1) $(cobimap 'a 'b 'c2) -- when a and b only occur in the last two parameters, c1 and c2
|
|
|
|
$(cobimap 'a 'b '(c -> d)) = \x e -> $(cobimap 'a 'b 'd) (x ($(bimap 'a 'b 'c) e))
|
|
|
|
``` |
|
|
|
\ No newline at end of file |