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

本当はすごい newtype

本当はすごい newtype

FIVE社ピザ会で 2018/08/07 に発表した、Haskell の newtype に関する講演です。
GHC 8.6.1 で導入される DerivingVia 言語拡張の説明もあります。

ソースコード:http://github.com/konn/newtype-talk-five

Hiromi Ishii

August 07, 2018
Tweet

More Decks by Hiromi Ishii

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ w ੴҪେւʢ!NS@LPOOʣ ͍ ͠ ͍ ͻ Ζ Έ w

    ਺ֶઐ߈ത࢜՝ఔ೥ w ਺ཧ࿦ཧֶͱܭࢉػՊֶͱ͔ w ؾ͚ͮ͹)BTLFMMྺ೥
  2. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ module Data.Id (Id ()) where newtype Id =

    MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word
  3. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ module Data.Id (Id ()) where newtype Id =

    MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word ֎෦ʹ͸σʔλߏஙࢠ MkId͸Ӆṭ
  4. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ ࣮૷ͷڞ༗ module Data.Id (Id ()) where newtype Id

    = MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ֎෦ʹ͸σʔλߏஙࢠ MkId͸Ӆṭ
  5. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ ࣮૷ͷڞ༗ module Data.Id (Id ()) where newtype Id

    = MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷ͸ಋग़ෆՄͰ΋ Wordͷ࣮૷͕ڞ༗Ͱ͖Δ ֎෦ʹ͸σʔλߏஙࢠ MkId͸Ӆṭ
  6. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ ࣮૷ͷڞ༗ module Data.Id (Id ()) where newtype Id

    = MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷ͸ಋग़ෆՄͰ΋ Wordͷ࣮૷͕ڞ༗Ͱ͖Δ %FSJWJOH7JB ͰߋʹਐԽ ֎෦ʹ͸σʔλߏஙࢠ MkId͸Ӆṭ
  7. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ ࣮૷ͷڞ༗ ࣮૷ͷબ୒ module Data.Id (Id ()) where newtype

    Id = MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷ͸ಋग़ෆՄͰ΋ Wordͷ࣮૷͕ڞ༗Ͱ͖Δ %FSJWJOH7JB ͰߋʹਐԽ ֎෦ʹ͸σʔλߏஙࢠ MkId͸Ӆṭ
  8. newtypeͷͭͷ༻్ ࣮૷ͷӅṭ ࣮૷ͷڞ༗ ࣮૷ͷબ୒ {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id

    = MkId Word deriving (Num, Eq) ຊདྷ͸ಋग़ෆՄͰ΋ Wordͷ࣮૷͕ڞ༗Ͱ͖Δ %FSJWJOH7JB ͰߋʹਐԽ module Data.Id (Id ()) where newtype Id = MkId Word ܕͷ্Ͱ͸۠ผ Ͱ΋಺෦తʹ͸Word ֎෦ʹ͸σʔλߏஙࢠ MkId͸Ӆṭ
  9. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  10. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) Կ͔ࣅͨΑ͏ͳ͜ͱ΍ͬͯΜͳʜʜ ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  11. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) Կ͔ࣅͨΑ͏ͳ͜ͱ΍ͬͯΜͳʜʜ ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  12. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) Կ͔ࣅͨΑ͏ͳ͜ͱ΍ͬͯΜͳʜʜ ม׵ʴೋ߲ԋࢉ ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  13. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) Կ͔ࣅͨΑ͏ͳ͜ͱ΍ͬͯΜͳʜʜ ม׵ʴೋ߲ԋࢉ ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  14. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) Կ͔ࣅͨΑ͏ͳ͜ͱ΍ͬͯΜͳʜʜ ม׵ʴೋ߲ԋࢉ ୯Ґݩ ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  15. ղ౴ྫ ৞ΈࠐΈͩʂ aggregate :: [ℕ] ! (Maybe ℕ, ℕ) aggregate

    = foldr (λ a (m, s) ! (Just a `max` m, a + s)) (Nothing, 0) Կ͔ࣅͨΑ͏ͳ͜ͱ΍ͬͯΜͳʜʜ .POPJEͩʂ ม׵ʴೋ߲ԋࢉ ୯Ґݩ ˞ℕ͸*OUFHFSͷུͩͱࢥ͍ͬͯͩ͘͞
  16. .POPJE w ࠨӈͷผͳ͘ܭࢉͰ͖ͯɺ୯Ґݩ͕͋Δ΍ͭ • max ΋ + ΋…… • ࠨ͔Β΍ͬͯ΋ӈ͔Β΍ͬͯ΋ಉ͡

    • Nothing (࠷େ஋ແ͠) ͱ 0 ͕୯Ґݩ (ɛ) • ϞϊΠυม׵ʴ৞ΈࠐΈ ⤳ Foldable! x ∙ (y ∙ z) = (x ∙ y) ∙ z x ∙ ε = x = ε ∙ x
  17. 'PMEBCMFܕΫϥε class Foldable t where foldMap :: Monoid m 㱺

    (a ! m) ! t a ! m … ϞϊΠυʹม׵
  ࠨ͔Β৞ΈࠐΈ
  18. 'PMEBCMFܕΫϥε ͜ͷ࿮૊ΈʹNBY  ΛམͱͤΕ͹Αͦ͞͏ class Foldable t where foldMap ::

    Monoid m 㱺 (a ! m) ! t a ! m … ϞϊΠυʹม׵
  ࠨ͔Β৞ΈࠐΈ
  19. Πϯελϯεྫ 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
  20. Πϯελϯεྫ 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 ਺ͷՃ๏ʹؔ͢Δ
 ϞϊΠυ
  21. Πϯελϯεྫ 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 ਺ͷՃ๏ʹؔ͢Δ
 ϞϊΠυ ࠷େݶʹؔ͢Δ
 ൒܈
  22. Πϯελϯεྫ 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 ਺ͷՃ๏ʹؔ͢Δ
 ϞϊΠυ ࠷େݶʹؔ͢Δ
 ൒܈ (/%ʹΑΔ
 ࣮૷ͷڞ༗
  23. 'PMEBCMF/FXUZQF൛ import Control.Arrow aggregate :: [ℕ] ! (Maybe ℕ, ℕ)

    aggregate = fmap getMax *** getSum ◦ foldMap (Just . Max &&& Sum)
  24. 'PMEBCMF/FXUZQF൛ ਵ෼͖ͬ͢Γʂ import Control.Arrow aggregate :: [ℕ] ! (Maybe ℕ,

    ℕ) aggregate = fmap getMax *** getSum ◦ foldMap (Just . Max &&& Sum)
  25. 'PMEBCMF/FXUZQF൛ ਵ෼͖ͬ͢Γʂ Ͱ΋Ұʑ.BY 4VNΛണ͢ͷ͸μϧ͍ͳ͋ʜʜωε τͯ͠Δ͠ʜʜ import Control.Arrow aggregate :: [ℕ]

    ! (Maybe ℕ, ℕ) aggregate = fmap getMax *** getSum ◦ foldMap (Just . Max &&& Sum) ‎;FSP$PTU$PFSDJPOT
  26. ͜ΕΛ࢖͑͹ʜʜ import Control.Arrow aggregate :: [ℕ] ! (Maybe ℕ, ℕ)

    aggregate = fmap getMax *** getSum ◦ foldMap (Just . Max &&& Sum)
  27. ͜͏ͳΓ·͢ import Control.Arrow import Data.Coerce aggregate :: [ℕ] ! (Maybe

    ℕ, ℕ) aggregate = coerce ◦ foldMap (Just . Max &&& Sum)
  28. ͜͏ͳΓ·͢ import Control.Arrow import Data.Coerce aggregate :: [ℕ] ! (Maybe

    ℕ, ℕ) aggregate = coerce ◦ foldMap (Just . Max &&& Sum) ω ε τ ܕ ΋  θ ϩ ί ε τ Ͱ ม ׵ ʂ
  29. ͜͏ͳΓ·͢ import Control.Arrow import Data.Coerce aggregate :: [ℕ] ! (Maybe

    ℕ, ℕ) aggregate = coerce ◦ foldMap (Just . Max &&& Sum) coerce :: (Maybe (Max ), Sum ) → (Maybe , ) ω ε τ ܕ ΋  θ ϩ ί ε τ Ͱ ม ׵ ʂ
  30. ͜͏ͳΓ·͢ import Control.Arrow import Data.Coerce aggregate :: [ℕ] ! (Maybe

    ℕ, ℕ) aggregate = coerce ◦ foldMap (Just . Max &&& Sum) w θϩίετͳͷͰɺ૸ࠪ͸Ұճ͚ͩ coerce :: (Maybe (Max ), Sum ) → (Maybe , ) ω ε τ ܕ ΋  θ ϩ ί ε τ Ͱ ม ׵ ʂ
  31. ͜͏ͳΓ·͢ import Control.Arrow import Data.Coerce aggregate :: [ℕ] ! (Maybe

    ℕ, ℕ) aggregate = coerce ◦ foldMap (Just . Max &&& Sum) w θϩίετͳͷͰɺ૸ࠪ͸Ұճ͚ͩ w લޙͷܕ͕͔ͬ͠Γܾ·͍ͬͯΔͷͰDPFSDFҰൃͰऴྃ coerce :: (Maybe (Max ), Sum ) → (Maybe , ) ω ε τ ܕ ΋  θ ϩ ί ε τ Ͱ ม ׵ ʂ
  32. ωετܕͷม׵ ͲΜͳίϯςφதͷܕ΋ม׵Ͱ͖ͯศརʂ ຊ౰ʹʁ newtype Down a = Down a instance

    Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a
  33. ωετܕͷม׵ ͲΜͳίϯςφதͷܕ΋ม׵Ͱ͖ͯศརʂ ຊ౰ʹʁ newtype Down a = Down a instance

    Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a ٯॱΛೖΕΔ
  34. ωετܕͷม׵ ͲΜͳίϯςφதͷܕ΋ม׵Ͱ͖ͯศརʂ ຊ౰ʹʁ newtype Down a = Down a instance

    Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a ٯॱΛೖΕΔ ώʔϓ
  35. ωετܕͷม׵ ͲΜͳίϯςφதͷܕ΋ม׵Ͱ͖ͯศརʂ ຊ౰ʹʁ newtype Down a = Down a instance

    Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a ٯॱΛೖΕΔ ώʔϓ ࠷খݩ0 
  36. ωετܕͷม׵ ͲΜͳίϯςφதͷܕ΋ม׵Ͱ͖ͯศརʂ ຊ౰ʹʁ newtype Down a = Down a instance

    Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a ҙຯ࿦తʹ Heap aͱHeap (Down a)͸Ωϟετग़དྷͳ͍΂͖ ٯॱΛೖΕΔ ώʔϓ ࠷খݩ0 
  37. ͦ͜Ͱ3PMFT w ͜ͷ··Ͱ͸DPFSDFͰม׵ग़དྷͯ͠·͏ʂ ghci> h = fromList [1,2,3] :: Heap

    Int ghci> minView (coerce h :: Heap (Down Int)) Just 1 Just 3Ͱ͋Δ΂͖ʂ
  38. ͦ͜Ͱ3PMFT w ͜ͷ··Ͱ͸DPFSDFͰม׵ग़དྷͯ͠·͏ʂ ghci> h = fromList [1,2,3] :: Heap

    Int ghci> minView (coerce h :: Heap (Down Int)) Just 1 w ͦ͜Ͱ3PMFΛࢦఆɿ Just 3Ͱ͋Δ΂͖ʂ
  39. ͦ͜Ͱ3PMFT w ͜ͷ··Ͱ͸DPFSDFͰม׵ग़དྷͯ͠·͏ʂ type role Heap nominal ghci> h =

    fromList [1,2,3] :: Heap Int ghci> minView (coerce h :: Heap (Down Int)) Just 1 w ͦ͜Ͱ3PMFΛࢦఆɿ Just 3Ͱ͋Δ΂͖ʂ
  40. ͦ͜Ͱ3PMFT w ͜ͷ··Ͱ͸DPFSDFͰม׵ग़དྷͯ͠·͏ʂ type role Heap nominal ghci> h =

    fromList [1,2,3] :: Heap Int ghci> minView (coerce h :: Heap (Down Int)) Just 1 w ͦ͜Ͱ3PMFΛࢦఆɿ ghci> minView (coerce h :: Heap (Down Int)) error: Couldn't match type ‘Int’ with ‘Down Int’ Just 3Ͱ͋Δ΂͖ʂ
  41. ͦ͜Ͱ3PMFT w ͜ͷ··Ͱ͸DPFSDFͰม׵ग़དྷͯ͠·͏ʂ type role Heap nominal ghci> h =

    fromList [1,2,3] :: Heap Int ghci> minView (coerce h :: Heap (Down Int)) Just 1 w ͦ͜Ͱ3PMFΛࢦఆɿ ghci> minView (coerce h :: Heap (Down Int)) error: Couldn't match type ‘Int’ with ‘Down Int’ Just 3Ͱ͋Δ΂͖ʂ w σʔλߏஙࢠΛ࿐ग़͠ͳ͚Ε͹ɺଞͷϞδϡʔϧͰ͸OPNJOBMʹਪ࿦͞ΕΔഺ
  42. ͦ͜Ͱ3PMFT w ͜ͷ··Ͱ͸DPFSDFͰม׵ग़དྷͯ͠·͏ʂ type role Heap nominal ghci> h =

    fromList [1,2,3] :: Heap Int ghci> minView (coerce h :: Heap (Down Int)) Just 1 w ͦ͜Ͱ3PMFΛࢦఆɿ ghci> minView (coerce h :: Heap (Down Int)) error: Couldn't match type ‘Int’ with ‘Down Int’ Just 3Ͱ͋Δ΂͖ʂ w σʔλߏஙࢠΛ࿐ग़͠ͳ͚Ε͹ɺଞͷϞδϡʔϧͰ͸OPNJOBMʹਪ࿦͞ΕΔഺ w OFXUZQFߏஙࢠͷ৘ใΛJNQPSU͠ͳ͍ͱDPFSDFͰ͖ͳ͍
  43. 3PMFTৄࡉ w 3PMFʮ͜ͷܕม਺͸͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w

    SFQSʮ͜͜͸಺෦දݱ͕ಉ͡ͳΒಉ஋ʯ w OPNJOBMʮ׬શʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ
  44. 3PMFTৄࡉ w 3PMFʮ͜ͷܕม਺͸͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w

    SFQSʮ͜͜͸಺෦දݱ͕ಉ͡ͳΒಉ஋ʯ w OPNJOBMʮ׬શʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂத਎ʹؔ܎ͳ͠ʯ
  45. 3PMFTৄࡉ w 3PMFʮ͜ͷܕม਺͸͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w

    SFQSʮ͜͜͸಺෦දݱ͕ಉ͡ͳΒಉ஋ʯ w OPNJOBMʮ׬શʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂத਎ʹؔ܎ͳ͠ʯ w ()$͸దٓ࠷΋ҰൠతͳSPMFΛਪ࿦ͯ͘͠ΕΔ
  46. 3PMFTৄࡉ w 3PMFʮ͜ͷܕม਺͸͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w

    SFQSʮ͜͜͸಺෦දݱ͕ಉ͡ͳΒಉ஋ʯ w OPNJOBMʮ׬શʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂத਎ʹؔ܎ͳ͠ʯ w ()$͸దٓ࠷΋ҰൠతͳSPMFΛਪ࿦ͯ͘͠ΕΔ w σʔλܕݻ༗ͷҙຯ࿦͸Ϣʔβ͔͠஌Βͳ͍ͷͰɺࠓճͷΑ ͏ͳέʔεͰ͸ϥΠϒϥϦ࣮૷ऀ͕ࢦఆ
  47. 3PMFTৄࡉ w 3PMFʮ͜ͷܕม਺͸͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w

    SFQSʮ͜͜͸಺෦දݱ͕ಉ͡ͳΒಉ஋ʯ w OPNJOBMʮ׬શʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂத਎ʹؔ܎ͳ͠ʯ w ()$͸దٓ࠷΋ҰൠతͳSPMFΛਪ࿦ͯ͘͠ΕΔ w σʔλܕݻ༗ͷҙຯ࿦͸Ϣʔβ͔͠஌Βͳ͍ͷͰɺࠓճͷΑ ͏ͳέʔεͰ͸ϥΠϒϥϦ࣮૷ऀ͕ࢦఆ w OFXUZQFߏஙࢠͷ৘ใ͕ͳ͍ͱcoerce͸ෆՄೳ
  48. (/%͸ෆ݈શ 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))
  49. (/%͸ෆ݈શ 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)) (/%
  50. (/%͸ෆ݈શ 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)) (/% ೚ҙͷܕؒͷΩϟετʂ
  51. (/%͸ෆ݈શ 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))
  52. (/%͸ෆ݈શ 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)) (/%͸DPFSDF Λܦ༝͢ΔΑ͏ʹ
  53. (/%͸ෆ݈શ 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)) (/%͸DPFSDF Λܦ༝͢ΔΑ͏ʹ ()$͸ݡ͍ͷͰ BΛOPNJOBMʹਪ࿦
  54. (/%͸ෆ݈શ 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)) (/%͸DPFSDF Λܦ༝͢ΔΑ͏ʹ ()$͸ݡ͍ͷͰ BΛOPNJOBMʹਪ࿦ 3FKFDU
  55. ྫɿ*EͷϞϊΠυߏ଄ w લʹݟͨΑ͏ʹɺ8PSEͷϞϊΠυ࣮૷͸ෳ਺͋Δ w *EͰ͸ʮҰ൪৽͍͠*E ࠷େͷ*E ΛબͿʯԋࢉΛϞϊΠυԋ ࢉͱͯ͠࢖͍͔ͨͬͨͱ͢Δ w Max

    Word͸IdͱಉҰදݱɺ NBY  ʹؔ͠ϞϊΠυ {-# LANGUAGE DerivingVia #-} newtype Id = MkId Word deriving (Semigroup, Monoid) via Max Word
  56. ྫɿ*EͷϞϊΠυߏ଄ w લʹݟͨΑ͏ʹɺ8PSEͷϞϊΠυ࣮૷͸ෳ਺͋Δ w *EͰ͸ʮҰ൪৽͍͠*E ࠷େͷ*E ΛબͿʯԋࢉΛϞϊΠυԋ ࢉͱͯ͠࢖͍͔ͨͬͨͱ͢Δ w Max

    Word͸IdͱಉҰදݱɺ NBY  ʹؔ͠ϞϊΠυ w %FSJWJOH7JB͸͜ͷ࣮૷Λࣗಈతʹ*Eʹ্࣋ͪ͛ͯ͘ΕΔʂ {-# LANGUAGE DerivingVia #-} newtype Id = MkId Word deriving (Semigroup, Monoid) via Max Word
  57. ෳࡶͳྫ w ܕϨϕϧͰΤϯίʔυͷ࢓༷Λࢦఆ w '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
  58. ಉܕͷྫ 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"]} -}
  59. ಉܕͷྫ 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
  60. ·ͱΊ w OFXUZQFͷ༻్͸ࡾͭ w ࣮૷ͷӅṭʗ࣮૷ͷڞ༗ʗ࣮૷ͷબ୒ w %BUB$PFSDFΛ࢖͏ͱ಺෦දݱ͕ಉ͡ܕಉ࢜Λθϩ ίετͰΩϟετՄೳ w OFXUZQFͷग़ੈ͸͔͜͜Β࢝·ͬͨ

    w ෳ߹ܕ΋3PMFਪ࿦ɾḼऍͰద੾ʹѻ͑Δ w ()$͔Β%FSJWJOH7JBͰOFXUZQFʹΑΓ
 ಋग़અΛΧελϚΠζՄೳʹʂ
  61. ࢀߟจݙ 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.
  62. 7 ↵ M ↵ ' [ · ] 9! 7QH/JT

    ' <latexit sha1_base64="tdNbhyHmLM0k2MhCNVTaF9VDoQE=">AAAHwnicjVRNj9xEEK0dPiYMkGSBAxKXhk2iRHIGT0gEAs1qBQhxiZQPNok0HlYeu2fHGdtt3D1f6/WBK3+AAyeQEEL8DC78AQ75CYhjkLhw4HXZm9ld7c7G1tjdVe9Vvarq8SCLI21c98la44UXX3q5ee6V1quvvX7+wsX1Nx5oNckDuR2oWOWPBr6WcZTKbROZWD7Kcukng1g+HIw/s/6HU5nrSKVfmUUm+4m/m0bDKPANTDvra794A7kbpYWJxntZFJhJLsuWl/gmj+aiV7/VUGA1EqkKpXYE0k6SVGiZdTvtW0HiiFzNqm2Q9EXREmL/6he5lGJ4bV8UNtrImGJYesLz42zkl+IKEIl13i49j/EVtHbDVn7S8jIQe9c3nTD3Z30BGFBChruSlfT0zM8cf2KUM1Sp6Xo6yKPM6GhPQsQlb+rn2Si6VApkAtdeS+6SVhzilZbYg8wgVMYTfUuuC7HZ6yWH6YW+HsmwfzzcMRVfF56cY476XVRlG6GyZUNUHN72s7JE4ZXYslKL0mUaHpnJzsWNTtvlS5y+2Nh6i/i6o9Yb35JHISkKaEIJSUrJYB2TTxp3D++b9Jj6VNCA5lhpWHJgIkZJKqmFCBPYJWXwBTTGcxe7gvaY4QO9gG8VtkcjRMx5F0GD4owH/CH2VteqXHOoMXgajrIqU2VNsbf1as4UIEOMXw6moMvun+6v7lP3D/c39y/3vxVZbQzbpwXeg4ors50L3719/98zWQl3ZrRkrWCEsD5PFwaIutpvuzPG+qw4E64rA17hHmJ9tk7bWwPsR9xTO8eMLbbbQcWf7n3/9P7H9y4XV9yf3L/R5x/dJ+7v6HQ6/Sf4+a6898MKVfbUjXEqDis/sMV4V9XlmEbB50DyfB36AP1z2GOrmbFNo/M+n0q7q2aRI8YcuwC7GE8HPMlnI2d/xBPQ1GZldnYJ+zI+vSlUns5IOP+4xum6hgP1VSW27z6vY8ZJ6tJV/mfmXI2dvgBGwZIiUxWrssyRI6gxEuhrp2S4Tpv4vQ+05v9lzFmKE3Vb+3HdzjNLl5EC1SvYo2csgdi38JyxbYRVAR3L7hdQUPLt1FzDcz6c9agaWeNPqsdWbL9cMyAXJ9Q15W4soMLwlOx5cuouVDFbz/fVfHCj3XHbnbs3NrY+rT6fdI7eofcwoQ59SFv0Jd2hbQoa5xs3G93GZvPz5uPmN01dQRtrNedNOnI19/8HqpXY9Q==</latexit> <latexit sha1_base64="tdNbhyHmLM0k2MhCNVTaF9VDoQE=">AAAHwnicjVRNj9xEEK0dPiYMkGSBAxKXhk2iRHIGT0gEAs1qBQhxiZQPNok0HlYeu2fHGdtt3D1f6/WBK3+AAyeQEEL8DC78AQ75CYhjkLhw4HXZm9ld7c7G1tjdVe9Vvarq8SCLI21c98la44UXX3q5ee6V1quvvX7+wsX1Nx5oNckDuR2oWOWPBr6WcZTKbROZWD7Kcukng1g+HIw/s/6HU5nrSKVfmUUm+4m/m0bDKPANTDvra794A7kbpYWJxntZFJhJLsuWl/gmj+aiV7/VUGA1EqkKpXYE0k6SVGiZdTvtW0HiiFzNqm2Q9EXREmL/6he5lGJ4bV8UNtrImGJYesLz42zkl+IKEIl13i49j/EVtHbDVn7S8jIQe9c3nTD3Z30BGFBChruSlfT0zM8cf2KUM1Sp6Xo6yKPM6GhPQsQlb+rn2Si6VApkAtdeS+6SVhzilZbYg8wgVMYTfUuuC7HZ6yWH6YW+HsmwfzzcMRVfF56cY476XVRlG6GyZUNUHN72s7JE4ZXYslKL0mUaHpnJzsWNTtvlS5y+2Nh6i/i6o9Yb35JHISkKaEIJSUrJYB2TTxp3D++b9Jj6VNCA5lhpWHJgIkZJKqmFCBPYJWXwBTTGcxe7gvaY4QO9gG8VtkcjRMx5F0GD4owH/CH2VteqXHOoMXgajrIqU2VNsbf1as4UIEOMXw6moMvun+6v7lP3D/c39y/3vxVZbQzbpwXeg4ors50L3719/98zWQl3ZrRkrWCEsD5PFwaIutpvuzPG+qw4E64rA17hHmJ9tk7bWwPsR9xTO8eMLbbbQcWf7n3/9P7H9y4XV9yf3L/R5x/dJ+7v6HQ6/Sf4+a6898MKVfbUjXEqDis/sMV4V9XlmEbB50DyfB36AP1z2GOrmbFNo/M+n0q7q2aRI8YcuwC7GE8HPMlnI2d/xBPQ1GZldnYJ+zI+vSlUns5IOP+4xum6hgP1VSW27z6vY8ZJ6tJV/mfmXI2dvgBGwZIiUxWrssyRI6gxEuhrp2S4Tpv4vQ+05v9lzFmKE3Vb+3HdzjNLl5EC1SvYo2csgdi38JyxbYRVAR3L7hdQUPLt1FzDcz6c9agaWeNPqsdWbL9cMyAXJ9Q15W4soMLwlOx5cuouVDFbz/fVfHCj3XHbnbs3NrY+rT6fdI7eofcwoQ59SFv0Jd2hbQoa5xs3G93GZvPz5uPmN01dQRtrNedNOnI19/8HqpXY9Q==</latexit> <latexit sha1_base64="Pm67WE0QM/hXwwhDQS392B0sFDs=">AAAHwnicjVRLj9xEEK4dHhMGSLLAAYlLwyZRIjmDJyQCgWa1AoS4RMqDTSKNh5XH7tlxxi+6e17r9YErf4ADJ5AQQvwMLvwBDvkJiGOQuHDg67In+2B3FltjV1d/X9VXVT0e5HGkjes+WWs89/wLLzbPvdR6+ZVXz1+4uP7aA51NVCC3gyzO1KOBr2UcpXLbRCaWj3Il/WQQy4eD8Sd2/+FUKh1l6Rdmkct+4u+m0TAKfAPXzvraT95A7kZpYaLxXh4FZqJk2fIS36hoLnr1OxsKWCORZqHUjkDaSZIKLfNup30rSByhslm1DJK+KFpC7F/9TEkphtf2RWGjjYwphqUnPD/OR34prgCR2M3bpecxvoLW2/CVH7W8HMTe9U0nVP6sLwADSshwV7KSnp75ueNPTOYMs9R0PR2oKDc62pMQccmb+iofRZdKgUzg2uuAe0ArDvFKS+xBZhBmxhN9S64Lsdlrk8P0Ql+PZNg/Hu6Yii8LT84xR/02qrKNyPKDhmRxeNvPyxKFV2LLSi1Kl2l4ZCY7Fzc6bZcvcbqxsfUG8XUnW298TR6FlFFAE0pIUkoGdkw+adw9vG/SY+pTQQOaw9LwKGAiRkkqqYUIE/gl5dgLaIznLlYF7THDB3qBvVXYHo0QUfEqgoaMMy75Q6ytrlW55lBj8DQcZVWmyptibevVnClAhhg/Baagy+7v7s/uU/c39xf3D/efFVltDNunBd6DiivznQvfvHn/7zNZCXdmdMBawQjh/T9dGCDq6n3bnTHss+JMuK4c+Az3EPbZOm1vDbAfcE/tHHP22G4HFX+69+3T+x/eu1xccX9w/0Sfv3efuL+i0+n0r+DHu/LedytU2VM3xqk4rHzpi/GuqlOYRsHnQPJ8HXoP/XN4x1YzY59G530+lXZVzUIhxhyrAKsYTwc8yWdD8X7EE9DUZmV2dgnv5Xx6U6g8nZFw/nGN03UNS/VVJbbvPtsx4yR16Sr/MxVXY6cvgMngSZGpilV55sgR1BgJ9LVTMlynTfzeBVrz/zLmLMWJuq3/uG7nmafLSIHqM/ijZyyB2LfwnLFvBKuAjoPuF1BQ8u3UXMNzPpz1qBpZ40+qx1Zsv1wzIBcn1DXlbiygwvCU7Hly6i5UMVv4arrLb+R/jeVX88GNdsdtd+7e2Nj6uPp80jl6i97BhDr0Pm3R53SHtilonG/cbHQbm81Pm4+bXzV1BW2s1ZzX6cjV3P8XqT/Y8g==</latexit> <latexit sha1_base64="Pm67WE0QM/hXwwhDQS392B0sFDs=">AAAHwnicjVRLj9xEEK4dHhMGSLLAAYlLwyZRIjmDJyQCgWa1AoS4RMqDTSKNh5XH7tlxxi+6e17r9YErf4ADJ5AQQvwMLvwBDvkJiGOQuHDg67In+2B3FltjV1d/X9VXVT0e5HGkjes+WWs89/wLLzbPvdR6+ZVXz1+4uP7aA51NVCC3gyzO1KOBr2UcpXLbRCaWj3Il/WQQy4eD8Sd2/+FUKh1l6Rdmkct+4u+m0TAKfAPXzvraT95A7kZpYaLxXh4FZqJk2fIS36hoLnr1OxsKWCORZqHUjkDaSZIKLfNup30rSByhslm1DJK+KFpC7F/9TEkphtf2RWGjjYwphqUnPD/OR34prgCR2M3bpecxvoLW2/CVH7W8HMTe9U0nVP6sLwADSshwV7KSnp75ueNPTOYMs9R0PR2oKDc62pMQccmb+iofRZdKgUzg2uuAe0ArDvFKS+xBZhBmxhN9S64Lsdlrk8P0Ql+PZNg/Hu6Yii8LT84xR/02qrKNyPKDhmRxeNvPyxKFV2LLSi1Kl2l4ZCY7Fzc6bZcvcbqxsfUG8XUnW298TR6FlFFAE0pIUkoGdkw+adw9vG/SY+pTQQOaw9LwKGAiRkkqqYUIE/gl5dgLaIznLlYF7THDB3qBvVXYHo0QUfEqgoaMMy75Q6ytrlW55lBj8DQcZVWmyptibevVnClAhhg/Baagy+7v7s/uU/c39xf3D/efFVltDNunBd6DiivznQvfvHn/7zNZCXdmdMBawQjh/T9dGCDq6n3bnTHss+JMuK4c+Az3EPbZOm1vDbAfcE/tHHP22G4HFX+69+3T+x/eu1xccX9w/0Sfv3efuL+i0+n0r+DHu/LedytU2VM3xqk4rHzpi/GuqlOYRsHnQPJ8HXoP/XN4x1YzY59G530+lXZVzUIhxhyrAKsYTwc8yWdD8X7EE9DUZmV2dgnv5Xx6U6g8nZFw/nGN03UNS/VVJbbvPtsx4yR16Sr/MxVXY6cvgMngSZGpilV55sgR1BgJ9LVTMlynTfzeBVrz/zLmLMWJuq3/uG7nmafLSIHqM/ijZyyB2LfwnLFvBKuAjoPuF1BQ8u3UXMNzPpz1qBpZ40+qx1Zsv1wzIBcn1DXlbiygwvCU7Hly6i5UMVv4arrLb+R/jeVX88GNdsdtd+7e2Nj6uPp80jl6i97BhDr0Pm3R53SHtilonG/cbHQbm81Pm4+bXzV1BW2s1ZzX6cjV3P8XqT/Y8g==</latexit> <latexit sha1_base64="Pm67WE0QM/hXwwhDQS392B0sFDs=">AAAHwnicjVRLj9xEEK4dHhMGSLLAAYlLwyZRIjmDJyQCgWa1AoS4RMqDTSKNh5XH7tlxxi+6e17r9YErf4ADJ5AQQvwMLvwBDvkJiGOQuHDg67In+2B3FltjV1d/X9VXVT0e5HGkjes+WWs89/wLLzbPvdR6+ZVXz1+4uP7aA51NVCC3gyzO1KOBr2UcpXLbRCaWj3Il/WQQy4eD8Sd2/+FUKh1l6Rdmkct+4u+m0TAKfAPXzvraT95A7kZpYaLxXh4FZqJk2fIS36hoLnr1OxsKWCORZqHUjkDaSZIKLfNup30rSByhslm1DJK+KFpC7F/9TEkphtf2RWGjjYwphqUnPD/OR34prgCR2M3bpecxvoLW2/CVH7W8HMTe9U0nVP6sLwADSshwV7KSnp75ueNPTOYMs9R0PR2oKDc62pMQccmb+iofRZdKgUzg2uuAe0ArDvFKS+xBZhBmxhN9S64Lsdlrk8P0Ql+PZNg/Hu6Yii8LT84xR/02qrKNyPKDhmRxeNvPyxKFV2LLSi1Kl2l4ZCY7Fzc6bZcvcbqxsfUG8XUnW298TR6FlFFAE0pIUkoGdkw+adw9vG/SY+pTQQOaw9LwKGAiRkkqqYUIE/gl5dgLaIznLlYF7THDB3qBvVXYHo0QUfEqgoaMMy75Q6ytrlW55lBj8DQcZVWmyptibevVnClAhhg/Baagy+7v7s/uU/c39xf3D/efFVltDNunBd6DiivznQvfvHn/7zNZCXdmdMBawQjh/T9dGCDq6n3bnTHss+JMuK4c+Az3EPbZOm1vDbAfcE/tHHP22G4HFX+69+3T+x/eu1xccX9w/0Sfv3efuL+i0+n0r+DHu/LedytU2VM3xqk4rHzpi/GuqlOYRsHnQPJ8HXoP/XN4x1YzY59G530+lXZVzUIhxhyrAKsYTwc8yWdD8X7EE9DUZmV2dgnv5Xx6U6g8nZFw/nGN03UNS/VVJbbvPtsx4yR16Sr/MxVXY6cvgMngSZGpilV55sgR1BgJ9LVTMlynTfzeBVrz/zLmLMWJuq3/uG7nmafLSIHqM/ijZyyB2LfwnLFvBKuAjoPuF1BQ8u3UXMNzPpz1qBpZ40+qx1Zsv1wzIBcn1DXlbiygwvCU7Hly6i5UMVv4arrLb+R/jeVX88GNdsdtd+7e2Nj6uPp80jl6i97BhDr0Pm3R53SHtilonG/cbHQbm81Pm4+bXzV1BW2s1ZzX6cjV3P8XqT/Y8g==</latexit> <latexit sha1_base64="ANYJsV1o7EqABLg5Rf+zVsu2U6Y=">AAAHwnicjVRNj9xEEK2dABMGSLLhgsSlYZMokZzBExKBQLOKACEukfLBJpHGw8pj9+w4Y7uNu+dj1+sDV/4AB04gIYT4GVz4AxzyExDHIHHhwOuyJ7O72Z3F1tjV1e9Vvarq8SCLI21c9+la48xLL7/SPPtq67XX3zh3/sL6xYdaTfJAbgUqVvnjga9lHKVyy0Qmlo+zXPrJIJaPBuNP7f6jqcx1pNIvzW4m+4m/k0bDKPANXNvraz97A7kTpYWJxntZFJhJLsuWl/gmj+aiV7/VUMAaiVSFUjsCaSdJKrTMup32rSBxRK5m1TJI+qJoCbF/9fNcSjG8ti8KG21kTDEsPeH5cTbyS3EFiMRu3ik9j/EVtN6Gr/y45WUg9q5vOmHuz/oCMKCEDHckK+npmZ85/sQoZ6hS0/V0kEeZ0dGehIhL3tTPs1F0qRTIBK69ltwlrTjAKy2xB5lBqIwn+pZcF2Kz1yaH6YW+HsmwfzTcERVfFZ6cY476HVRlG6GyZUNUHN7xs7JE4ZXYslKL0mUaHprJ9oWNTtvlS5xsbFB93VXrjW/Io5AUBTShhCSlZGDH5JPG3cP7Jj2hPhU0oDksDU8OTMQoSSW1EGECv6QMewGN8dzBqqA9ZvhA72JvFbZHI0TMeRVBg+KMC/4Qa6trVa451Bg8DUdZlanypljbejVnCpAhxi8HU9Bl9w/3F/eZ+7v7q/un+++KrDaG7dMu3oOKK7Pt89++9eCfU1kJd2a0ZK1ghPD+ny4MEHX1vu3OGPZpcSZcVwa8wj2EfbpO21sD7IfcUzvHjD2220HFn+599+zBR/cvF1fcH92/0Ocf3Kfub+h0Ov07+OmevP/9ClX21I1xKg4qX/hivKvqckyj4HMgeb4OvY/+Obxjq5mxT6PzPp9Ku6pmkSPGHKsAqxhPBzzJZyPn/YgnoKnNyuzsEt7L+PSmUHkyI+H84xqn6xoW6qtKbN99tmPGSerSVf5n5lyNnb4ARsGTIlMVq/LMkSOoMRLoaydkuE6b+L0HtOb/ZcxZimN1W/9R3c5zT5eRAtUr+KPnLIHYt/CcsW8Eq4COZfcLKCj5dmqu4TkfzHpYjazxx9VjK7ZfrhmQu8fUNeVu7EKF4SnZ8+TUXahitvDVdBffyBeNxVfz4Y12x2137t3YuP1J/f08S2/Tu5hQhz6g2/QF3aUtChrnGjcb3cZm87Pmk+bXTV1BG2s15006dDX3/wPW8die</latexit> ࣗ༝Ϟφυͷීวੑ w ࣗ༝ϞϊΠυവखͷఆ͔ٛΒ w α͔ΒGα΁ͷೖࣹ w G͕വखͰ͋Δ͜ͱ w Gαࣗ਎͕ϞϊΠυͰ͋Δࣄ w ʜʜΛআ͘ͱ'PMEBCMFʹͳΔ w ௚઀࡞Δํ๏͕ͳͯ͘΋͍͍ w Hask ݍͷവखͱ͸ݶΒͳ͍ w ϞϊΠυͱ͸ݶΒͳ͍ɺ୯ͳΔ ໦ߏ଄Ͱ΋৞ΈࠐΈ͍ͨ
  63. 'PMEBCMFͱ5SBWFSTBCMF w 5SBWFSTBCMF͸ࣗ༝ϞϊΠυͱ'PMEBCMFͷதؒ w USBWFSTF͸ࣗ༝ϞϊΠυͳΒ؆୯ʹॻ͚Δ class (Pointed f, Foldable f,

    ∀a. Monoid (f a)) 㱺 FreeMonoid f instance (Pointed f, Foldable f, ∀a. Monoid (f a)) 㱺 FreeMonoid f fold :: (FreeMonoid f) 㱺 (a ! b ! b) ! b ! f a ! b fold g n xs = appEndo (foldMap (Endo . g) xs) n traverseF :: (FreeMonoid f, Applicative t) 㱺 (a ! t b) ! f a ! t (f b) traverseF f = fold (λa tb ! (<>) <$> (iota <$> f a) <*> tb) (pure mempty) ͔ΒೖΔ QuantifiedConstraints $PNQMFUFDPEFɿsrc/Data/Foldable/Monoid.hs