Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Great Power of newtypes

The Great Power of newtypes

This is the English translation of my Japanese talk at Five Corp, describing newtypes, Foldables and DerivingVia extensions (https://speakerdeck.com/konn/ben-dang-hasugoi-newtype?slide=167).

Hiromi Ishii

August 24, 2018
Tweet

More Decks by Hiromi Ishii

Other Decks in Programming

Transcript

  1. 5IF(SFBU1PXFSPG
    newtypeT
    !NS@LPOO
    IUUQTLPOOTBODPN
    4MJEFTBSFBWBJMBCMFBUhttp://bit.ly/derivia

    &YBNQMFDPEFTBSFPO(JU)VCkonn/newtype-talk-five

    View full-size slide

  2. 4FMG*OUSPEVDUJPO
    w )JSPNJ*4)**ʢ!NS@LPOOʣ
    w %PDUPSBM$BOEJEBUFJO.BUIFNBUJDT
    w 3FTFBSDI"SFB.BUIFNBUJDBM-PHJD
    $PNQVUFS4DJFODF
    w 8SJUJOHBOEUFBDIJOH)BTLFMMGPSZFBST

    View full-size slide

  3. 5IF(SFBU1PXFSPGnewtypeT
    3PMFT 4BGF[FSPDPTUDPFSDJPOT BOE%FSJWJOH7JB
    ʙ.POPJE&'PMEBCMFJODMVEFEʙ
    (SFBU

    View full-size slide

  4. newtype
    newtype Foo α = Bar α
    newtype Id = MkId Word

    View full-size slide

  5. newtype
    w "UZQFXJUIBTJOHMFDPOTUSVDUPSBOEpFME
    newtype Foo α = Bar α
    newtype Id = MkId Word

    View full-size slide

  6. newtype
    w "UZQFXJUIBTJOHMFDPOTUSVDUPSBOEpFME
    w )BTUIF4BNFSFQSFTFOUBUJPOBTJUTPOMZpFME
    newtype Foo α = Bar α
    newtype Id = MkId Word

    View full-size slide

  7. newtype
    w "UZQFXJUIBTJOHMFDPOTUSVDUPSBOEpFME
    w )BTUIF4BNFSFQSFTFOUBUJPOBTJUTPOMZpFME
    w %JTUJOHVJTIFEGSPNUIFPSJHJOBMUZQFBUUZQF
    MFWFM CVUIBTUIFTBNFNFNPSZSFQSFTFOUBUJPO
    BTUIFPSJHJOBM BOEFWBMVBUFETUSJDUMZ
    newtype Foo α = Bar α
    newtype Id = MkId Word

    View full-size slide

  8. 5ZQJDBM/FXCJF2VFTUJPO

    View full-size slide

  9. 5ZQJDBM/FXCJF2VFTUJPO
    8IBUJTUIFEJ⒎FSFODFGSPNdata?"

    View full-size slide

  10. 5ZQJDBM/FXCJF2VFTUJPO
    8IBUJTUIFEJ⒎FSFODFGSPNdata?"
    *UTF⒏DJFOUUIBOLTUPJUTSFQSFTFOUBUJPO

    View full-size slide

  11. 5ZQJDBM/FXCJF2VFTUJPO
    8IBUJTUIFEJ⒎FSFODFGSPNdata?"
    *UTF⒏DJFOUUIBOLTUPJUTSFQSFTFOUBUJPO
    *UEPFTOUNBUUFSNVDIUPNF*ESBUIFS

    VTFdata

    View full-size slide

  12. 5ZQJDBM/FXCJF2VFTUJPO
    8IBUJTUIFEJ⒎FSFODFGSPNdata?"
    *UTF⒏DJFOUUIBOLTUPJUTSFQSFTFOUBUJPO
    *UEPFTOUNBUUFSNVDIUPNF*ESBUIFS

    VTFdata
    8FMM XFIBWFfunpack-strict-fieldsBOZIPX

    View full-size slide

  13. 3PMFTPGnewtypeT

    View full-size slide

  14. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    module Data.Id (Id ()) where
    newtype Id = MkId Word

    View full-size slide

  15. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    module Data.Id (Id ()) where
    newtype Id = MkId Word %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally

    View full-size slide

  16. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    module Data.Id (Id ()) where
    newtype Id = MkId Word %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally
    )JEFEBUBDPOTMkId

    outside the module

    View full-size slide

  17. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    *NQMFNFOUBUJPO4IBSJOH
    module Data.Id (Id ()) where
    newtype Id = MkId Word %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    newtype Id = MkId Word deriving (Num, Eq)
    )JEFEBUBDPOTMkId

    outside the module

    View full-size slide

  18. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    *NQMFNFOUBUJPO4IBSJOH
    module Data.Id (Id ()) where
    newtype Id = MkId Word %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    newtype Id = MkId Word deriving (Num, Eq)
    6OEFSJWBCMFJO)BTLFMM
    CVUXFDBOTIBSFWordTJNQM
    )JEFEBUBDPOTMkId

    outside the module

    View full-size slide

  19. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    *NQMFNFOUBUJPO4IBSJOH
    module Data.Id (Id ()) where
    newtype Id = MkId Word %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    newtype Id = MkId Word deriving (Num, Eq)
    6OEFSJWBCMFJO)BTLFMM
    CVUXFDBOTIBSFWordTJNQM
    &WPMWFT
    NPSFJO
    %FSJWJOH7JB
    )JEFEBUBDPOTMkId

    outside the module

    View full-size slide

  20. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    *NQMFNFOUBUJPO4IBSJOH
    *NQMFNFOUBUJPO4FMFDUJPO
    module Data.Id (Id ()) where
    newtype Id = MkId Word %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    newtype Id = MkId Word deriving (Num, Eq)
    6OEFSJWBCMFJO)BTLFMM
    CVUXFDBOTIBSFWordTJNQM
    &WPMWFT
    NPSFJO
    %FSJWJOH7JB
    )JEFEBUBDPOTMkId

    outside the module

    View full-size slide

  21. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    *NQMFNFOUBUJPO4IBSJOH
    *NQMFNFOUBUJPO4FMFDUJPO
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    newtype Id = MkId Word deriving (Num, Eq)
    6OEFSJWBCMFJO)BTLFMM
    CVUXFDBOTIBSFWordTJNQM
    &WPMWFT
    NPSFJO
    %FSJWJOH7JB
    module Data.Id (Id ()) where
    newtype Id = MkId Word
    )JEFEBUBDPOTMkId

    outside the module

    View full-size slide

  22. 3PMFTPGnewtypeT
    *NQMFNFOUBUJPO)JEJOH
    *NQMFNFOUBUJPO4IBSJOH
    *NQMFNFOUBUJPO4FMFDUJPO
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    newtype Id = MkId Word deriving (Num, Eq)
    6OEFSJWBCMFJO)BTLFMM
    CVUXFDBOTIBSFWordTJNQM
    &WPMWFT
    NPSFJO
    %FSJWJOH7JB
    module Data.Id (Id ()) where
    newtype Id = MkId Word
    )JEFEBUBDPOTMkId

    outside the module
    %JTUJOHVJTIFEBUUZQFMFWFM
    CVUKVTUBWord internally

    View full-size slide

  23. *NQMFNFOUBUJPO
    4FMFDUJPO

    View full-size slide

  24. *NQMFNFOUBUJPO
    4FMFDUJPO
    .POPJE'PMEBCMFBT&YBNQMFT

    View full-size slide

  25. &YFSDJTF-JTU4DBOOJOH
    2 (JWFOBMJTUPGJOUFHFST DBMDVMBUFTJUTNBYJNVN
    BOEUPUBMTVNCZTDBOOJOHMJTUFYBDUMZPODF
    ˞%POPUVTFfoldlPSfoldsQBDLBHFT

    View full-size slide

  26. 5ZQJDBM"OTXFS

    View full-size slide

  27. 5ZQJDBM"OTXFS
    'PMET

    View full-size slide

  28. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  29. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    8FIBWFTJNJMBSPQFSBUJPOTPOCPUITJEFT
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  30. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    8FIBWFTJNJMBSPQFSBUJPOTPOCPUITJEFT
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  31. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    8FIBWFTJNJMBSPQFSBUJPOTPOCPUITJEFT
    .BQ#JOBSZ
    0QFSBUJPO
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  32. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    8FIBWFTJNJMBSPQFSBUJPOTPOCPUITJEFT
    .BQ#JOBSZ
    0QFSBUJPO
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  33. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    8FIBWFTJNJMBSPQFSBUJPOTPOCPUITJEFT
    .BQ#JOBSZ
    0QFSBUJPO
    6OJUT
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  34. 5ZQJDBM"OTXFS
    'PMET
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate = foldr
    (λ a (m, s) " (Just a `max` m, a + s))
    (Nothing, 0)
    8FIBWFTJNJMBSPQFSBUJPOTPOCPUITJEFT
    .POPJET
    .BQ#JOBSZ
    0QFSBUJPO
    6OJUT
    ˞ℕJTTIPSUGPS*OUFHFS

    View full-size slide

  35. .POPJET
    w "OPQFSBUJPOXIJDIDBOCFDPNQVUFECPUI
    GSPNMFGUBOESJHIU XJUIVOJUFMFNFOU
    • Both `max` and (+)
    • … can be computed from either left or
    right,
    • … has Nothing (no max) and 0 as units.
    • Mapping to monoid + folding ⤳ Foldable!
    x ∙ (y ∙ z) = (x ∙ y) ∙ z
    x ∙ ε = x = ε ∙ x

    View full-size slide

  36. 'PMEBCMFDMBTT
    class Foldable t where
    foldMap :: Monoid m 㱺 (a " m) " t a " m

    View full-size slide

  37. 'PMEBCMFDMBTT
    class Foldable t where
    foldMap :: Monoid m 㱺 (a " m) " t a " m

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View full-size slide

  38. 'PMEBCMFDMBTT
    *UTV⒏DFTUPNBLFNBY
    pUJOUIJTGSBNFXPSL
    class Foldable t where
    foldMap :: Monoid m 㱺 (a " m) " t a " m

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View full-size slide

  39. 'PMEBCMFDMBTT
    *UTV⒏DFTUPNBLFNBY
    pUJOUIJTGSBNFXPSL
    8FDBOIBWFBUNPTUPOFJOTUBODFGPSMonoid Word
    class Foldable t where
    foldMap :: Monoid m 㱺 (a " m) " t a " m

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View full-size slide

  40. 'PMEBCMFDMBTT
    *UTV⒏DFTUPNBLFNBY
    pUJOUIJTGSBNFXPSL
    8FDBOIBWFBUNPTUPOFJOTUBODFGPSMonoid Word
    *NQMFNFOUBUJPO4FMFDUJPOVTJOHnewtypeT
    class Foldable t where
    foldMap :: Monoid m 㱺 (a " m) " t a " m

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View full-size slide

  41. &YBNQMFJOTUBODFT
    newtype Sum a = Sum { getSum :: a}
    deriving (Num, Integral)
    instance Num a 㱺 Monoid (Sum a) where
    (<>) = (+); ε = 0
    newtype Max a = Max { getMax :: a }
    deriving (Num, Integral, Ord)
    instance Ord a 㱺 Semigroup (Max a) where
    (<>) = max

    View full-size slide

  42. &YBNQMFJOTUBODFT
    newtype Sum a = Sum { getSum :: a}
    deriving (Num, Integral)
    instance Num a 㱺 Monoid (Sum a) where
    (<>) = (+); ε = 0
    newtype Max a = Max { getMax :: a }
    deriving (Num, Integral, Ord)
    instance Ord a 㱺 Semigroup (Max a) where
    (<>) = max
    .POPJEPG
    OVNFSJDBEEJUJPO

    View full-size slide

  43. &YBNQMFJOTUBODFT
    newtype Sum a = Sum { getSum :: a}
    deriving (Num, Integral)
    instance Num a 㱺 Monoid (Sum a) where
    (<>) = (+); ε = 0
    newtype Max a = Max { getMax :: a }
    deriving (Num, Integral, Ord)
    instance Ord a 㱺 Semigroup (Max a) where
    (<>) = max
    .POPJEPG
    OVNFSJDBEEJUJPO
    4FNJHSPVQCZ
    UBLJOHNBY

    View full-size slide

  44. &YBNQMFJOTUBODFT
    newtype Sum a = Sum { getSum :: a}
    deriving (Num, Integral)
    instance Num a 㱺 Monoid (Sum a) where
    (<>) = (+); ε = 0
    newtype Max a = Max { getMax :: a }
    deriving (Num, Integral, Ord)
    instance Ord a 㱺 Semigroup (Max a) where
    (<>) = max
    .POPJEPG
    OVNFSJDBEEJUJPO
    4FNJHSPVQCZ
    UBLJOHNBY
    *NQMTIBSJOHCZ
    (/%

    View full-size slide

  45. 1SBDUJDBM3FNBSL
    w 0OMZCPVOEFEUZQFTDBOCF\max min^NPOPJET 8F
    OFFENBYJNVNNJOJNVNFMFNFOUUPIBWFUIFVOJU

    w 8FTUJMMIBWFB4FNJSJOH XIJDIMBDLTVOJUT
    w 8FIBWFUPDPOWFSUJUUPNPOPJEUPVTFXJUI'PMEBCMF
    newtype Max a = Max a
    instance Ord a 㱺 Semigroup (Max a)
    instance Bounded a 㱺 Monoid (Max a)

    View full-size slide

  46. 1SBDUJDBM3FNBSL
    newtype Option a = Option (Maybe a)
    instance Semigroup a 㱺 Monoid (Option a)

    View full-size slide

  47. 1SBDUJDBM3FNBSL
    OptionBEKPJOTVOJU UVSOJOHTFNJHSPVQTJOUPNPOPJET
    newtype Option a = Option (Maybe a)
    instance Semigroup a 㱺 Monoid (Option a)

    View full-size slide

  48. 1SBDUJDBM3FNBSL
    OptionBEKPJOTVOJU UVSOJOHTFNJHSPVQTJOUPNPOPJET
    ʙ()$ɿ.BZCFSFRVJSFT.POPJEBBTBDPOTUSBJOU
    newtype Option a = Option (Maybe a)
    instance Semigroup a 㱺 Monoid (Option a)
    instance Monoid a 㱺 Monoid (Maybe a)

    View full-size slide

  49. 1SBDUJDBM3FNBSL
    OptionBEKPJOTVOJU UVSOJOHTFNJHSPVQTJOUPNPOPJET
    ʙ()$ɿ.BZCFSFRVJSFT.POPJEBBTBDPOTUSBJOU
    ()$ʙɿ3FRVJSFTPOMZSemigroup a, no need of
    0QUJPO
    newtype Option a = Option (Maybe a)
    instance Semigroup a 㱺 Monoid (Option a)
    instance Monoid a 㱺 Monoid (Maybe a)
    instance Semigroup a 㱺 Monoid (Maybe a)

    View full-size slide

  50. 1SBDUJDBM3FNBSL
    OptionBEKPJOTVOJU UVSOJOHTFNJHSPVQTJOUPNPOPJET
    ʙ()$ɿ.BZCFSFRVJSFT.POPJEBBTBDPOTUSBJOU
    ()$ʙɿ3FRVJSFTPOMZSemigroup a, no need of
    0QUJPO
    8FTUJMMIBWFUPVTF0QUJPOUPXSJUFBQPSUBCMFDPEFTUIPVHI
    newtype Option a = Option (Maybe a)
    instance Semigroup a 㱺 Monoid (Option a)
    instance Monoid a 㱺 Monoid (Maybe a)
    instance Semigroup a 㱺 Monoid (Maybe a)

    View full-size slide

  51. 'PMEBCMFOFXUZQFWFSTJPO
    import Control.Arrow
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    fmap getMax *** getSum
    ○ foldMap (Just . Max &&& Sum)

    View full-size slide

  52. 'PMEBCMFOFXUZQFWFSTJPO
    4PDPODJTF
    import Control.Arrow
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    fmap getMax *** getSum
    ○ foldMap (Just . Max &&& Sum)

    View full-size slide

  53. 'PMEBCMFOFXUZQFWFSTJPO
    4PDPODJTF
    *UTTUJMMUFEJPVTUPVOXSBQ.BYBOE4VNUIFZ
    TJUTJOOFTUFEUZQFT
    import Control.Arrow
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    fmap getMax *** getSum
    ○ foldMap (Just . Max &&& Sum)

    View full-size slide

  54. 'PMEBCMFOFXUZQFWFSTJPO
    4PDPODJTF
    *UTTUJMMUFEJPVTUPVOXSBQ.BYBOE4VNUIFZ
    TJUTJOOFTUFEUZQFT
    import Control.Arrow
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    fmap getMax *** getSum
    ○ foldMap (Just . Max &&& Sum)
    ‎;FSP$PTU$PFSDJPOT

    View full-size slide

  55. 4BGF;FSP$PTU
    $PFSDJPOTBOE3PMFT

    View full-size slide

  56. 4BGF;FSP$PTU
    $PFSDJPOTBOE3PMFT
    [1] Breitner, Eisenberg, Peyton Jones and Weirich, 2014
    "HSFBUJOWFOUJPO

    PQFOJOHVQUIFOFXFSBPGOFXUZQFT

    View full-size slide

  57. #FGPSF
    )BTLFMMFSTDPNQMBJOU

    View full-size slide

  58. *OEFFE OFXUZQFTBSF
    DPOWJOFOUGPSJNQM
    TFMFDUJPO

    View full-size slide

  59. #VUXFIBWFUPVOXSBQ
    UIFNPOFCZPOF

    View full-size slide

  60. %PJOHTPJTOPUTP
    F⒏DJFOU

    View full-size slide

  61. 4JODFXFLOPXJUTTBGF
    XFDBOVTF
    VOTBGF$PFSDF

    View full-size slide

  62. *UTOPURVJUFTNBSU

    View full-size slide

  63. *O 

    5IF3FWPMVUJPOUPPLQMBDF
    UPOFXUZQFT

    View full-size slide

  64. ;FSP$PTU$PFSDJPO

    View full-size slide

  65. ;FSP$PTU$PFSDJPO
    import Data.Coerce (coerce)
    coerce :: Coercible a b 㱺 a " b

    View full-size slide

  66. ;FSP$PTU$PFSDJPO
    w $PFSDJCMFSFMBUFTUXPUZQFTXJUIUIFTBNFNFNPSZSFQS
    import Data.Coerce (coerce)
    coerce :: Coercible a b 㱺 a " b

    View full-size slide

  67. ;FSP$PTU$PFSDJPO
    w $PFSDJCMFSFMBUFTUXPUZQFTXJUIUIFTBNFNFNPSZSFQS
    w *UTFFNTMJLFBUZQFDMBTT CVU()$HFOFSBUFTBOJOGPSNBUJPO
    BUDPNQJMFUJNF BOEVTFSDBOOPUBEEDVTUPNJOTUBODF
    import Data.Coerce (coerce)
    coerce :: Coercible a b 㱺 a " b

    View full-size slide

  68. ;FSP$PTU$PFSDJPO
    w $PFSDJCMFSFMBUFTUXPUZQFTXJUIUIFTBNFNFNPSZSFQS
    w *UTFFNTMJLFBUZQFDMBTT CVU()$HFOFSBUFTBOJOGPSNBUJPO
    BUDPNQJMFUJNF BOEVTFSDBOOPUBEEDVTUPNJOTUBODF
    w 8JUIcoerceGSPNData.Coerce XFDBOEP[FSPDPTUDBTUT
    import Data.Coerce (coerce)
    coerce :: Coercible a b 㱺 a " b

    View full-size slide

  69. ;FSP$PTU$PFSDJPO
    w $PFSDJCMFSFMBUFTUXPUZQFTXJUIUIFTBNFNFNPSZSFQS
    w *UTFFNTMJLFBUZQFDMBTT CVU()$HFOFSBUFTBOJOGPSNBUJPO
    BUDPNQJMFUJNF BOEVTFSDBOOPUBEEDVTUPNJOTUBODF
    w 8JUIcoerceGSPNData.Coerce XFDBOEP[FSPDPTUDBTUT
    w *OGFSSFEQFSNPEVMF XFOFFEUIFJOGPPGEBUBDPOTUSVDUPS
    UPDBMMcoerce
    import Data.Coerce (coerce)
    coerce :: Coercible a b 㱺 a " b

    View full-size slide

  70. 8JUIDPFSDF
    import Control.Arrow
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    fmap getMax *** getSum
    ○ foldMap (Just . Max &&& Sum)

    View full-size slide

  71. 8FHFUJU
    import Control.Arrow
    import Data.Coerce
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    coerce ○ foldMap (Just . Max &&& Sum)

    View full-size slide

  72. 8FHFUJU
    import Control.Arrow
    import Data.Coerce
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    coerce ○ foldMap (Just . Max &&& Sum)
    $BTUJOH
    OFTUFE
    UZQFTXJUI[FSP
    DPTU

    View full-size slide

  73. 8FHFUJU
    import Control.Arrow
    import Data.Coerce
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    coerce ○ foldMap (Just . Max &&& Sum)
    coerce :: (Maybe (Max ), Sum ) → (Maybe , )
    $BTUJOH
    OFTUFE
    UZQFTXJUI[FSP
    DPTU

    View full-size slide

  74. 8FHFUJU
    import Control.Arrow
    import Data.Coerce
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    coerce ○ foldMap (Just . Max &&& Sum)
    w /PF⒎FDUPOUIFPGTDBOOJOHTJODFJUT[FSPDPTU
    coerce :: (Maybe (Max ), Sum ) → (Maybe , )
    $BTUJOH
    OFTUFE
    UZQFTXJUI[FSP
    DPTU

    View full-size slide

  75. 8FHFUJU
    import Control.Arrow
    import Data.Coerce
    aggregate :: [ℕ] " (Maybe ℕ, ℕ)
    aggregate =
    coerce ○ foldMap (Just . Max &&& Sum)
    w /PF⒎FDUPOUIFPGTDBOOJOHTJODFJUT[FSPDPTU
    w +VTUPOFDBMMGPSDPFSDFUPNBLFJUEPOF
    coerce :: (Maybe (Max ), Sum ) → (Maybe , )
    $BTUJOH
    OFTUFE
    UZQFTXJUI[FSP
    DPTU

    View full-size slide

  76. $BTUJOHCXOFTUFEUZQFT

    View full-size slide

  77. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT

    View full-size slide

  78. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ

    View full-size slide

  79. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ
    newtype Down a = Down a
    instance Ord a 㱺 Ord (Down a) where
    a ≤ b = b ≤ a
    data Heap a
    minView :: Heap a " Maybe a

    View full-size slide

  80. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ
    newtype Down a = Down a
    instance Ord a 㱺 Ord (Down a) where
    a ≤ b = b ≤ a
    data Heap a
    minView :: Heap a " Maybe a
    3FWFSTFE0SEFS

    View full-size slide

  81. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ
    newtype Down a = Down a
    instance Ord a 㱺 Ord (Down a) where
    a ≤ b = b ≤ a
    data Heap a
    minView :: Heap a " Maybe a
    3FWFSTFE0SEFS
    )FBQ

    View full-size slide

  82. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ
    newtype Down a = Down a
    instance Ord a 㱺 Ord (Down a) where
    a ≤ b = b ≤ a
    data Heap a
    minView :: Heap a " Maybe a
    3FWFSTFE0SEFS
    )FBQ
    .JOJNVN 0

    View full-size slide

  83. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ
    newtype Down a = Down a
    instance Ord a 㱺 Ord (Down a) where
    a ≤ b = b ≤ a
    data Heap a
    minView :: Heap a " Maybe a
    4FNBOUJDBMMZ Heap a.645/05CFDBTUFEUPHeap (Down a)
    3FWFSTFE0SEFS
    )FBQ
    .JOJNVN 0

    View full-size slide

  84. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF

    View full-size slide

  85. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF
    ghci> h = fromList [1,2,3] :: Heap Int
    ghci> minView (coerce h :: Heap (Down Int))
    Just 1

    View full-size slide

  86. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF
    ghci> h = fromList [1,2,3] :: Heap Int
    ghci> minView (coerce h :: Heap (Down Int))
    Just 1 .VTUCFJust 3!

    View full-size slide

  87. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF
    ghci> h = fromList [1,2,3] :: Heap Int
    ghci> minView (coerce h :: Heap (Down Int))
    Just 1
    w 5IFOXFTQFDJGZUIF3PMF
    .VTUCFJust 3!

    View full-size slide

  88. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF
    type role Heap nominal
    ghci> h = fromList [1,2,3] :: Heap Int
    ghci> minView (coerce h :: Heap (Down Int))
    Just 1
    w 5IFOXFTQFDJGZUIF3PMF
    .VTUCFJust 3!

    View full-size slide

  89. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF
    type role Heap nominal
    ghci> h = fromList [1,2,3] :: Heap Int
    ghci> minView (coerce h :: Heap (Down Int))
    Just 1
    w 5IFOXFTQFDJGZUIF3PMF
    ghci> minView (coerce h :: Heap (Down Int))
    error: Couldn't match type ‘Int’ with ‘Down Int’
    .VTUCFJust 3!

    View full-size slide

  90. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF
    type role Heap nominal
    ghci> h = fromList [1,2,3] :: Heap Int
    ghci> minView (coerce h :: Heap (Down Int))
    Just 1
    w 5IFOXFTQFDJGZUIF3PMF
    ghci> minView (coerce h :: Heap (Down Int))
    error: Couldn't match type ‘Int’ with ‘Down Int’
    .VTUCFJust 3!
    w 8FDBOOPUDPFSDFXJUIPVUUIFJOGPPGOFXUZQFDPOTUSVDUPST

    View full-size slide

  91. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT

    View full-size slide

  92. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom

    View full-size slide

  93. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom
    w SFQSFRVJWBMFOUJGUIFZIBWFUIFTBNFSFQSFTFOUBUJPO

    View full-size slide

  94. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom
    w SFQSFRVJWBMFOUJGUIFZIBWFUIFTBNFSFQSFTFOUBUJPO
    w OPNJOBMNVTUIBWFFYBDUMZUIFTBNFUZQF

    View full-size slide

  95. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom
    w SFQSFRVJWBMFOUJGUIFZIBWFUIFTBNFSFQSFTFOUBUJPO
    w OPNJOBMNVTUIBWFFYBDUMZUIFTBNFUZQF
    w QIBOUPNVOSFMBUFEUPJUTSFBMDPOUFOUBOZUIJOHHPFT

    View full-size slide

  96. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom
    w SFQSFRVJWBMFOUJGUIFZIBWFUIFTBNFSFQSFTFOUBUJPO
    w OPNJOBMNVTUIBWFFYBDUMZUIFTBNFUZQF
    w QIBOUPNVOSFMBUFEUPJUTSFBMDPOUFOUBOZUIJOHHPFT
    w ()$JOGFSTNPTUHFOFSBMSPMFTBUFWFSZUJNF

    View full-size slide

  97. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom
    w SFQSFRVJWBMFOUJGUIFZIBWFUIFTBNFSFQSFTFOUBUJPO
    w OPNJOBMNVTUIBWFFYBDUMZUIFTBNFUZQF
    w QIBOUPNVOSFMBUFEUPJUTSFBMDPOUFOUBOZUIJOHHPFT
    w ()$JOGFSTNPTUHFOFSBMSPMFTBUFWFSZUJNF
    w 4PNFUJNFTMJCSBSZJNQMFNFOUPSNVTUTQFDJGZSPMFT CFDBVTF
    ()$DBOUUFMMUIFTFNBOUJDTTQFDJpDUPUIFQBSUJDVMBSUZQF

    View full-size slide

  98. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT
    w 5ISFFLJOETrepresentational / nominal / phantom
    w SFQSFRVJWBMFOUJGUIFZIBWFUIFTBNFSFQSFTFOUBUJPO
    w OPNJOBMNVTUIBWFFYBDUMZUIFTBNFUZQF
    w QIBOUPNVOSFMBUFEUPJUTSFBMDPOUFOUBOZUIJOHHPFT
    w ()$JOGFSTNPTUHFOFSBMSPMFTBUFWFSZUJNF
    w 4PNFUJNFTMJCSBSZJNQMFNFOUPSNVTUTQFDJGZSPMFT CFDBVTF
    ()$DBOUUFMMUIFTFNBOUJDTTQFDJpDUPUIFQBSUJDVMBSUZQF
    w 8FDBOUDPFSDFUZQFTXJUIPVOFXUZQFDPOTUSVDUPSJOGP

    View full-size slide

  99. $PFSDJPO3PMFT4VNNBSZ
    w 8JUIDPFSDFGVODUJPO XFDBODBTUOFTUUZQFT
    XJUIUIFTBNFSFQSFTFOUBUJPO XJUI[FSPDPTU
    w 8FDBOVTFOFXUZQFTNPSFTBGFMZBOE
    DPOWFOJFOUMZ
    w 8FDBODPOUSPMDBTUBCJMJUZCZTQFDJGZJOH3PMFT
    w 3PMFTBSFVTVBMMZJOGFSSFE
    w 8FIBWFUPTQFDJGZSPMFTXIFOXFXBOUUP
    EJTBMMPXDBTUTGPSUIFTFNBOUJDBMSFBTPOT

    View full-size slide

  100. :FT 5IBUTXIBUXF
    XBOUFE

    View full-size slide

  101. 8IZXFEJEOUIBWF
    UIJT

    View full-size slide

  102. 1SFIJTUPSZPG;FSP$PTU
    $PFSDJPO(/%DSJTJT
    w 8FIBWF(FOFSBMJ[FE/FXUZQF%FSJWJOH
    (/%
    BULFBTUBMSFBEZJO()$
    w "UUIBUUJNF ()$IBEPOMZBUBNFUZQF
    TZTUFN FWFSZUIJOHXBTpOF
    w -BUFS UZQFGBNJMJFT ("%5TBOETPPODBNF
    JOUPUIF()$TUZQFTZTUFNBOE
    w (/%CFDBNFVOPVOE

    View full-size slide

  103. (/%XBTVOTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))

    View full-size slide

  104. (/%XBTVOTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))
    (/%

    View full-size slide

  105. (/%XBTVOTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))
    (/%
    $BTUCXBOZUZQFT

    View full-size slide

  106. 5IBUTUFSSJCMF

    View full-size slide

  107. 8FIBWFUPTBWFUIF
    (/%

    View full-size slide

  108. 5IBUTXIZ3PMFT
    BSFFNFSHFE

    View full-size slide

  109. (/%JT6OTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))

    View full-size slide

  110. (/%JT6OTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))
    (/%CFDBNFUP
    VTFDPFSDF

    View full-size slide

  111. (/%JT6OTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))
    (/%CFDBNFUP
    VTFDPFSDF
    ()$JTDMFWFS
    FOPVHIUPJOGFSa
    BTOPNJOBM

    View full-size slide

  112. (/%JT6OTPVOE
    newtype Id1 a = MkId1 a
    newtype Id2 a = MkId2 (Id1 a)
    deriving (UnsafeCast b)
    type family Discern a b
    type instance Discern (Id1 a) b = a
    type instance Discern (Id2 a) b = b
    class UnsafeCast to from where
    unsafe :: from " Discern from to
    instance UnsafeCast b (Id1 a) where
    unsafe (MkId1 x) = x
    unsafeCoerce :: a " b
    unsafeCoerce x = unsafe (MkId2 (MkId1 x))
    (/%CFDBNFUP
    VTFDPFSDF
    ()$JTDMFWFS
    FOPVHIUPJOGFSa
    BTOPNJOBM
    3FKFDU

    View full-size slide

  113. /PX OFXUZQFTDBO
    QMBZUIFJSSPMFT

    UIBOLTUP3PMFT

    View full-size slide

  114. 3PMFTPGOFXUZQFT

    View full-size slide

  115. *NQMFNFOUBUJPO

    )JEJOH

    View full-size slide

  116. *NQMFNFOUBUJPO

    4IBSJOH

    View full-size slide

  117. *NQMFNFOUBUJPO

    4FMFDUJPO

    View full-size slide

  118. 5IJTJTXIFSF

    OFXUZQFT
    TUBOETOPX

    View full-size slide

  119. 'SPNOPXPO
    5IFGVUVSFPG
    OFXUZQF

    View full-size slide

  120. 5IFGVUVSFPGOFXUZQFT
    PS%FSJWJOH7JB

    View full-size slide

  121. 5IFGVUVSFPGOFXUZQFT
    PS%FSJWJOH7JB
    d8IFOUIFJNQMTIBSJOHBOETFMFDUJPONFFUd
    [2] Blöndal, Löh and Scott, 2018

    View full-size slide

  122. %FSJWJOH7JB.PSF'MFYJCMF
    *NQMFNFOUBUJPO4IBSJOH

    View full-size slide

  123. %FSJWJOH7JB.PSF'MFYJCMF
    *NQMFNFOUBUJPO4IBSJOH
    w "OFXGFBUVSFPG()$

    View full-size slide

  124. %FSJWJOH7JB.PSF'MFYJCMF
    *NQMFNFOUBUJPO4IBSJOH
    w "OFXGFBUVSFPG()$
    w ()$BMQIBJTSFMFBTFEBUUIFUJNF
    PGUIJTUBML

    View full-size slide

  125. %FSJWJOH7JB.PSF'MFYJCMF
    *NQMFNFOUBUJPO4IBSJOH
    w "OFXGFBUVSFPG()$
    w ()$BMQIBJTSFMFBTFEBUUIFUJNF
    PGUIJTUBML
    w 8FDBOVTFOFXUZQFTBTBIJOUGPSEFSJWJOH
    DMBVTFT

    View full-size slide

  126. &H.POPJETUSVDUVSFPG*E
    {-# LANGUAGE DerivingVia #-}
    newtype Id = MkId Word
    deriving (Semigroup, Monoid) via Max Word

    View full-size slide

  127. &H.POPJETUSVDUVSFPG*E
    w "TXFIBWFTFFO 8PSEIBWFNVMUJQMFNPOPJEJNQMT
    {-# LANGUAGE DerivingVia #-}
    newtype Id = MkId Word
    deriving (Semigroup, Monoid) via Max Word

    View full-size slide

  128. &H.POPJETUSVDUVSFPG*E
    w "TXFIBWFTFFO 8PSEIBWFNVMUJQMFNPOPJEJNQMT
    w 4VQQPTFXFXBOUUPVTFDIPPTJOHUIFOFXFTU*E .BYJNVN
    *E
    BTNPOPJEPQFSBUJPOPO*ET
    {-# LANGUAGE DerivingVia #-}
    newtype Id = MkId Word
    deriving (Semigroup, Monoid) via Max Word

    View full-size slide

  129. &H.POPJETUSVDUVSFPG*E
    w "TXFIBWFTFFO 8PSEIBWFNVMUJQMFNPOPJEJNQMT
    w 4VQQPTFXFXBOUUPVTFDIPPTJOHUIFOFXFTU*E .BYJNVN
    *E
    BTNPOPJEPQFSBUJPOPO*ET
    w Max WordIBTUIFTBNFSFQSBTId GPSNTBNPOPJEXJUI
    SFTQFDUUP NBY

    {-# LANGUAGE DerivingVia #-}
    newtype Id = MkId Word
    deriving (Semigroup, Monoid) via Max Word

    View full-size slide

  130. &H.POPJETUSVDUVSFPG*E
    w "TXFIBWFTFFO 8PSEIBWFNVMUJQMFNPOPJEJNQMT
    w 4VQQPTFXFXBOUUPVTFDIPPTJOHUIFOFXFTU*E .BYJNVN
    *E
    BTNPOPJEPQFSBUJPOPO*ET
    w Max WordIBTUIFTBNFSFQSBTId GPSNTBNPOPJEXJUI
    SFTQFDUUP NBY

    w %FSJWJOH7JBDBOMJGUUIJTJNQMBVUPNBUJDBMMZUP*E
    {-# LANGUAGE DerivingVia #-}
    newtype Id = MkId Word
    deriving (Semigroup, Monoid) via Max Word

    View full-size slide

  131. %FSJWJOH7JBWT(/%

    View full-size slide

  132. %FSJWJOH7JBWT(/%
    w %FSJWJOH7JBJTBTVQFSTFUPG(/%

    View full-size slide

  133. %FSJWJOH7JBWT(/%
    w %FSJWJOH7JBJTBTVQFSTFUPG(/%
    w (/%KVTUMPPLTBUUIFJOOFSNPTUUZQF

    View full-size slide

  134. %FSJWJOH7JBWT(/%
    w %FSJWJOH7JBJTBTVQFSTFUPG(/%
    w (/%KVTUMPPLTBUUIFJOOFSNPTUUZQF
    w %FSJWJOH7JBMFUVTSFVTFUIFJNQMPGBOZ
    $PFSDJCMFUZQFT XJUIPVUBOZDPTU

    View full-size slide

  135. %FSJWJOH7JBJTOPUMJNJUFEUP
    OFXUZQFT

    View full-size slide

  136. %FSJWJOH7JBJTOPUMJNJUFEUP
    OFXUZQFT
    w *OUIFPSJHJOBMQBQFS JUJTQSPQPTFEUPVTF
    %FSJWJOH7JBUPTIBSFJNQMFNFOUBUJPOT
    CFUXFFOBOZJTPNPQIJDUZQFT
    ˞5IJTJTPNPSQIJDNFBOTTMJHIUMZTUSPOHFSDPOEJUJPO

    ɹJUNFBOTUIFJSHFOFSJDSFQSFTFOUBUJPOJTUIFTBNF

    View full-size slide

  137. %FSJWJOH7JBJTOPUMJNJUFEUP
    OFXUZQFT
    w *OUIFPSJHJOBMQBQFS JUJTQSPQPTFEUPVTF
    %FSJWJOH7JBUPTIBSFJNQMFNFOUBUJPOT
    CFUXFFOBOZJTPNPQIJDUZQFT
    $PNCJOBUJPOPG(FOFSJDTBOE$PFSDJPO
    ˞5IJTJTPNPSQIJDNFBOTTMJHIUMZTUSPOHFSDPOEJUJPO

    ɹJUNFBOTUIFJSHFOFSJDSFQSFTFOUBUJPOJTUIFTBNF

    View full-size slide

  138. %FNP
    4UBUJDEFpOJUJPOPG+40/EFTFSJBMJ[BUJPOJOTUBODF
    *NQMTIBSJOHCXJTPNPSQIJDUZQFT
    ˞$PNQMFUFDPEFJTBWBJMBCMFBUhttp://bit.ly/derivia

    View full-size slide

  139. $PNQMJDBUFE&YBNQMF
    w 4QFDJpFTUIFFODPEJOHNFUIPEBUUZQFMFWFM
    w 4UBUJDBMMZBTTVSFTUIBUTBNFFODPEJOHJTVTFEJO'SPN+40/5P+40/
    data OtherConfig = OtherConfig
    { otrNameOfProcess :: Maybe String
    , otrArgsToProcess :: [String]
    }
    deriving (Read, Show, Eq, Ord, Generic)
    deriving (ToJSON, FromJSON)
    via WithOptions '[ FieldLabelModifier '[CamelTo2 "-"]
    , ConstructorTagModifier '[CamelTo2 "-"]
    , OmitNothingFields 'True
    ]
    OtherConfig

    View full-size slide

  140. &YBNQMFPG*TP
    data Blog = Blog { authors :: [Author]
    , articles :: [Article] }
    deriving (Generic)
    deriving (Semigroup, Monoid)
    via Blog `SameRepAs` ([Author], Dual [Article])
    {-
    ghci> mconcat [Blog ["1"] ["1"], Blog ["2"] ["3","4"]]
    Blog {authors = ["1","2"], articles = ["3","4","1"]}
    -}

    View full-size slide

  141. &YBNQMFPG*TP DPOU

    newtype SameRepAs a b = SameRepAs { runSameRepAs :: a }
    type Iso a b = (Generic a, Generic b,
    Coercible (Rep a ()) (Rep b ()))
    instance (Semigroup b, Iso a b)
    㱺 Semigroup (SameRepAs a b) where
    SameRepAs a <> SameRepAs b = ...
    instance (Monoid b, Iso a b)
    㱺 Monoid (SameRepAs a b) where
    mempty = SameRepAs $ toA mempty
    where
    toA :: b -> a
    toA = to . (coerce :: Rep b () -> Rep a ()) . from

    View full-size slide

  142. %FSJWJOH7JB4VNNBSZ

    View full-size slide

  143. %FSJWJOH7JB4VNNBSZ
    w "WBJMBCMFTJODF()$

    View full-size slide

  144. %FSJWJOH7JB4VNNBSZ
    w "WBJMBCMFTJODF()$
    w 8FDBOVTFOFXUZQFTUPTQFDJGZUIFJNQMGPS
    EFSJWJOHDMBVTFT

    View full-size slide

  145. %FSJWJOH7JB4VNNBSZ
    w "WBJMBCMFTJODF()$
    w 8FDBOVTFOFXUZQFTUPTQFDJGZUIFJNQMGPS
    EFSJWJOHDMBVTFT
    w $PNCJOFEXJUI(FOFSJDT XFDBOFWFOEFSJWFUIF
    JOTUBODFGSPNJTPNPSQIJDUZQF CVUOPU
    OFDFTTBSJMZSFQSFTFOUBUJPOBMMZFRVBM

    View full-size slide

  146. %FSJWJOH7JB4VNNBSZ
    w "WBJMBCMFTJODF()$
    w 8FDBOVTFOFXUZQFTUPTQFDJGZUIFJNQMGPS
    EFSJWJOHDMBVTFT
    w $PNCJOFEXJUI(FOFSJDT XFDBOFWFOEFSJWFUIF
    JOTUBODFGSPNJTPNPSQIJDUZQF CVUOPU
    OFDFTTBSJMZSFQSFTFOUBUJPOBMMZFRVBM
    w "OZPUIFSJTPNPSQIJTNFYQSFTTJCMFBTBUZQF
    DPOTUSBJOUJTBMTPBQQMJDBCMFUPUIJTUFDIOJRVF

    View full-size slide

  147. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT

    View full-size slide

  148. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT
    w *NQMFNFOUBUJPO)JEJOH4IBSJOH4FMFDUJPO

    View full-size slide

  149. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT
    w *NQMFNFOUBUJPO)JEJOH4IBSJOH4FMFDUJPO
    w 8JUI%BUB$PFSDF XFDBODBTUSFQSFTFOUBUJPOBMMZ
    FRVBMMUZQFTXJUI[FSPDPTU

    View full-size slide

  150. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT
    w *NQMFNFOUBUJPO)JEJOH4IBSJOH4FMFDUJPO
    w 8JUI%BUB$PFSDF XFDBODBTUSFQSFTFOUBUJPOBMMZ
    FRVBMMUZQFTXJUI[FSPDPTU
    w 5IFOFXUZQF3FWPMVUJPOTUBSUFEIFSF

    View full-size slide

  151. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT
    w *NQMFNFOUBUJPO)JEJOH4IBSJOH4FMFDUJPO
    w 8JUI%BUB$PFSDF XFDBODBTUSFQSFTFOUBUJPOBMMZ
    FRVBMMUZQFTXJUI[FSPDPTU
    w 5IFOFXUZQF3FWPMVUJPOTUBSUFEIFSF
    w 8FDBOUSFBUDPNQPVOEUZQFTQSPQFSMZXJUISPMF
    JOGFSFODFBOEBOOPUBUJPOT

    View full-size slide

  152. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT
    w *NQMFNFOUBUJPO)JEJOH4IBSJOH4FMFDUJPO
    w 8JUI%BUB$PFSDF XFDBODBTUSFQSFTFOUBUJPOBMMZ
    FRVBMMUZQFTXJUI[FSPDPTU
    w 5IFOFXUZQF3FWPMVUJPOTUBSUFEIFSF
    w 8FDBOUSFBUDPNQPVOEUZQFTQSPQFSMZXJUISPMF
    JOGFSFODFBOEBOOPUBUJPOT
    w 4JODF()$ %FSJWJOH7JBFOBCMFTVTUPVTF
    OFXUZQFUPDVTUPNJTFUIFEFSJWJOHDMBVTFT

    View full-size slide

  153. 3FGFSFODFT
    1. J. Breitner, R. A. Eisenberg, S. P. Jones and S.
    Weirich, Safe Zero-cost Coercions for Haskell,
    ICFP 2014.
    2. Baldur Blöndal, Andres Löh and Ryan Scott,
    Deriving Via: How to Turn Hand-Written
    Instances into an Anti-Pattern, ICFP18.

    View full-size slide