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
    [email protected]
    IUUQTLPOOTBODPN
    4MJEFTBSFBWBJMBCMFBUhttp://bit.ly/derivia

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

    View Slide

  2. 4FMG*OUSPEVDUJPO
    w )JSPNJ*4)**ʢ[email protected]ʣ
    w %PDUPSBM$BOEJEBUFJO.BUIFNBUJDT
    w 3FTFBSDI"SFB.BUIFNBUJDBM-PHJD
    $PNQVUFS4DJFODF
    w 8SJUJOHBOEUFBDIJOH)BTLFMMGPSZFBST

    View Slide

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

    View Slide

  4. newtype

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. 5ZQJDBM/FXCJF2VFTUJPO

    View Slide

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

    View Slide

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

    View Slide

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

    VTFdata

    View Slide

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

    VTFdata
    8FMM XFIBWFfunpack-strict-fieldsBOZIPX

    View Slide

  14. 3FBMMZ

    View Slide

  15. 3PMFTPGnewtypeT

    View Slide

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

    View Slide

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

    View Slide

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

    outside the module

    View 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)
    )JEFEBUBDPOTMkId

    outside the module

    View Slide

  20. 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 Slide

  21. 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 Slide

  22. 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 Slide

  23. 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 Slide

  24. 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 Slide

  25. *NQMFNFOUBUJPO
    4FMFDUJPO

    View Slide

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

    View Slide

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

    View Slide

  28. 5ZQJDBM"OTXFS

    View Slide

  29. 5ZQJDBM"OTXFS
    'PMET

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. 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 Slide

  34. 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 Slide

  35. 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 Slide

  36. 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 Slide

  37. .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 Slide

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

    View Slide

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

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View Slide

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

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View Slide

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

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View Slide

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

    .BQUP.POPJE


    'PMEMFGUUPSJHIU

    View 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

    View 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

    View Slide

  45. &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 Slide

  46. &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 Slide

  47. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  51. 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 Slide

  52. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  57. 4BGF;FSP$PTU
    $PFSDJPOTBOE3PMFT

    View Slide

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

    PQFOJOHVQUIFOFXFSBPGOFXUZQFT

    View Slide

  59. #FGPSF
    )BTLFMMFSTDPNQMBJOU

    View Slide

  60. *OEFFE OFXUZQFTBSF
    DPOWJOFOUGPSJNQM
    TFMFDUJPO

    View Slide

  61. #VUXFIBWFUPVOXSBQ
    UIFNPOFCZPOF

    View Slide

  62. %PJOHTPJTOPUTP
    F⒏DJFOU

    View Slide

  63. 4JODFXFLOPXJUTTBGF
    XFDBOVTF
    VOTBGF$PFSDF

    View Slide

  64. *UTOPURVJUFTNBSU

    View Slide

  65. #VU

    View Slide

  66. *O 

    5IF3FWPMVUJPOUPPLQMBDF
    UPOFXUZQFT

    View Slide

  67. ;FSP$PTU$PFSDJPO

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  71. ;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 Slide

  72. ;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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  76. 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 Slide

  77. 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 Slide

  78. 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 Slide

  79. $BTUJOHCXOFTUFEUZQFT

    View Slide

  80. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT

    View Slide

  81. $BTUJOHCXOFTUFEUZQFT
    *UTDPOWFOJFOUUIBUXFDBODBTUBOZOFTUFEUZQFT
    3FBMMZ

    View 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

    View 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
    3FWFSTFE0SEFS

    View Slide

  84. $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 Slide

  85. $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 Slide

  86. $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 Slide

  87. 3PMFT

    View Slide

  88. 3PMFT
    w 8FDBODBTUUIFNXJUIDPFSDF

    View Slide

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

    View Slide

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

    View Slide

  91. 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 Slide

  92. 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 Slide

  93. 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 Slide

  94. 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 Slide

  95. .PSFPO3PMFT

    View Slide

  96. .PSFPO3PMFT
    w 3PMF5IFUZQFWBSJBCMFIFSFCFIBWFTMJLFUIJT

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  105. :FT 5IBUTXIBUXF
    XBOUFE

    View Slide

  106. 8IZXFEJEOUIBWF
    UIJT

    View Slide

  107. 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 Slide

  108. (/%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 Slide

  109. (/%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 Slide

  110. (/%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 Slide

  111. 5IBUTUFSSJCMF

    View Slide

  112. 8FIBWFUPTBWFUIF
    (/%

    View Slide

  113. 5IBUTXIZ3PMFT
    BSFFNFSHFE

    View Slide

  114. (/%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 Slide

  115. (/%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 Slide

  116. (/%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 Slide

  117. (/%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 Slide


  118. View Slide

  119. /PX OFXUZQFTDBO
    QMBZUIFJSSPMFT

    UIBOLTUP3PMFT

    View Slide

  120. 3PMFTPGOFXUZQFT

    View Slide

  121. *NQMFNFOUBUJPO

    )JEJOH

    View Slide

  122. *NQMFNFOUBUJPO

    4IBSJOH

    View Slide

  123. *NQMFNFOUBUJPO

    4FMFDUJPO

    View Slide

  124. 5IJTJTXIFSF

    OFXUZQFT
    TUBOETOPX

    View Slide

  125. 'SPNOPXPO
    5IFGVUVSFPG
    OFXUZQF

    View Slide

  126. 5IFGVUVSFPGOFXUZQFT
    PS%FSJWJOH7JB

    View Slide

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

    View Slide

  128. %FSJWJOH7JB.PSF'MFYJCMF
    *NQMFNFOUBUJPO4IBSJOH

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  134. &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 Slide

  135. &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 Slide

  136. &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 Slide

  137. %FSJWJOH7JBWT(/%

    View Slide

  138. %FSJWJOH7JBWT(/%
    w %FSJWJOH7JBJTBTVQFSTFUPG(/%

    View Slide

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

    View Slide

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

    View Slide

  141. %FSJWJOH7JBJTOPUMJNJUFEUP
    OFXUZQFT

    View Slide

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

    ɹJUNFBOTUIFJSHFOFSJDSFQSFTFOUBUJPOJTUIFTBNF

    View Slide

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

    ɹJUNFBOTUIFJSHFOFSJDSFQSFTFOUBUJPOJTUIFTBNF

    View Slide

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

    View Slide

  145. $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 Slide

  146. &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 Slide

  147. &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 Slide

  148. %FSJWJOH7JB4VNNBSZ

    View Slide

  149. %FSJWJOH7JB4VNNBSZ
    w "WBJMBCMFTJODF()$

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  153. 4VNNBSZ

    View Slide

  154. 4VNNBSZ

    View Slide

  155. 4VNNBSZ
    w 5ISFFSPMFTPGOFXUZQFT

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  161. 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 Slide