Changes between Version 15 and Version 16 of Commentary/Compiler/DeriveFunctor


Ignore:
Timestamp:
Apr 18, 2016 11:33:24 PM (4 years ago)
Author:
RyanGlScott
Comment:

Details

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/DeriveFunctor

    v15 v16  
    447447
    448448== Future work ==
    449 The `Bifunctor` class (born from the [http://hackage.haskell.org/package/bifunctors bifunctors] library) [https://ghc.haskell.org/trac/ghc/ticket/9682 was added] to `base` in GHC 7.10, and [https://ghc.haskell.org/trac/ghc/ticket/10448 there are plans] to add `Bifoldable` and `Bitraversable` to `base` in the future. All three classes could be derived in much the same way as their cousins `Functor`, `Foldable`, and `Traversable`. The existing algorithms would simply need to be adapted to accommodate two type parameters instead of one.
    450 
    451 The [https://github.com/ekmett/bifunctors/blob/8e975aead363802610dedccf414b884f9b39b1f4/src/Data/Bifunctor/TH.hs Data.Bifunctor.TH ] module from the `bifunctors` library demonstrates an implementation of the following proposal using Template Haskell.
     449There are more classes in `base` that we could derive!
     450
     451In particular, the `Bifunctor` class (born from the [http://hackage.haskell.org/package/bifunctors bifunctors] library) [https://ghc.haskell.org/trac/ghc/ticket/9682 was added] to `base` in GHC 7.10, and [https://ghc.haskell.org/trac/ghc/ticket/10448 there are plans] to add `Bifoldable` and `Bitraversable` to `base` in the future. All three classes could be derived in much the same way as their cousins `Functor`, `Foldable`, and `Traversable`. The existing algorithms would simply need to be adapted to accommodate two type parameters instead of one. The [https://github.com/ekmett/bifunctors/blob/c2e7717e1913dc53ad934b3d0ddd74d077b965c3/src/Data/Bifunctor/TH.hs Data.Bifunctor.TH] module from the `bifunctors` library demonstrates an implementation of the following proposal using Template Haskell.
     452
     453In GHC 8.0, higher-order versions of the `Eq`, `Ord`, `Read`, and `Show` typeclasses were added to `base` in the `Data.Functor.Classes` module (which originally lived in the `transformers` library). These classes are generalized to work over datatypes indexed by one type parameter (for `Eq1`, `Ord1`, `Read1`, and `Show1`) or by two type parameters (`Eq2`, `Ord2`, `Read2`, and `Show2`). Haskell programmers have been able to derive `Eq`, `Ord`, `Read`, and `Show` for a long time, so it wouldn't be hard at all to envision a deriving mechanism for `Eq1`, `Eq2`, and friends which takes advantage of tricks that `DeriveFunctor` uses.
    452454
    453455=== Classes ===
    454456
    455 The classes are defined as follows:
     457The `Bifunctor`, `Bifoldable`, and `Bitraversable` classes are defined as follows:
    456458
    457459{{{#!hs
     
    468470
    469471Each 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`.
     472
     473The typeclasses in `Data.Functor.Classes` are defined as follows:
     474
     475{{{#!hs
     476class Eq1 f where
     477    liftEq :: (a -> b -> Bool) -> f a -> f b -> Bool
     478
     479class (Eq1 f) => Ord1 f where
     480    liftCompare :: (a -> b -> Ordering) -> f a -> f b -> Ordering
     481
     482class Read1 f where
     483    liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
     484    liftReadList  :: (Int -> ReadS a) -> ReadS [a]        -> ReadS [f a]
     485
     486class Show1 f where
     487    liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int ->  f a  -> ShowS
     488    liftShowList  :: (Int -> a -> ShowS) -> ([a] -> ShowS)        -> [f a] -> ShowS
     489
     490class Eq2 f where
     491    liftEq2 :: (a -> b -> Bool) -> (c -> d -> Bool) -> f a c -> f b d -> Bool
     492
     493class (Eq2 f) => Ord2 f where
     494    liftCompare2 :: (a -> b -> Ordering) -> (c -> d -> Ordering) -> f a c -> f b d -> Ordering
     495
     496class Read2 f where
     497    liftReadsPrec2 :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> Int -> ReadS (f a b)
     498    liftReadList2  :: (Int -> ReadS a) -> ReadS [a] -> (Int -> ReadS b) -> ReadS [b]        -> ReadS [f a b]
     499
     500class Show2 f where
     501    liftShowsPrec2 :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS) -> Int ->  f a b - > ShowS
     502    liftShowList2  :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> (Int -> b -> ShowS) -> ([b] -> ShowS)        -> [f a b] -> ShowS
     503}}}
    470504
    471505=== Algorithms ===