newtypeͷͭͷ༻్ ࣮ͷӅṭ ࣮ͷڞ༗ module Data.Id (Id ()) where newtype Id = MkId Word ܕͷ্Ͱ۠ผ Ͱ෦తʹWord {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ֎෦ʹσʔλߏஙࢠ MkIdӅṭ
newtypeͷͭͷ༻్ ࣮ͷӅṭ ࣮ͷڞ༗ module Data.Id (Id ()) where newtype Id = MkId Word ܕͷ্Ͱ۠ผ Ͱ෦తʹWord {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷಋग़ෆՄͰ Wordͷ࣮͕ڞ༗Ͱ͖Δ ֎෦ʹσʔλߏஙࢠ MkIdӅṭ
newtypeͷͭͷ༻్ ࣮ͷӅṭ ࣮ͷڞ༗ module Data.Id (Id ()) where newtype Id = MkId Word ܕͷ্Ͱ۠ผ Ͱ෦తʹWord {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷಋग़ෆՄͰ Wordͷ࣮͕ڞ༗Ͱ͖Δ %FSJWJOH7JB ͰߋʹਐԽ ֎෦ʹσʔλߏஙࢠ MkIdӅṭ
newtypeͷͭͷ༻్ ࣮ͷӅṭ ࣮ͷڞ༗ ࣮ͷબ module Data.Id (Id ()) where newtype Id = MkId Word ܕͷ্Ͱ۠ผ Ͱ෦తʹWord {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷಋग़ෆՄͰ Wordͷ࣮͕ڞ༗Ͱ͖Δ %FSJWJOH7JB ͰߋʹਐԽ ֎෦ʹσʔλߏஙࢠ MkIdӅṭ
newtypeͷͭͷ༻్ ࣮ͷӅṭ ࣮ͷڞ༗ ࣮ͷબ {-# LANGUAGE GeneralizedNewtypeDeriving #-} newtype Id = MkId Word deriving (Num, Eq) ຊདྷಋग़ෆՄͰ Wordͷ࣮͕ڞ༗Ͱ͖Δ %FSJWJOH7JB ͰߋʹਐԽ module Data.Id (Id ()) where newtype Id = MkId Word ܕͷ্Ͱ۠ผ Ͱ෦తʹWord ֎෦ʹσʔλߏஙࢠ MkIdӅṭ
'PMEBCMFܕΫϥε ͜ͷΈʹNBY
ΛམͱͤΕΑͦ͞͏ Monoid WordΠϯελϯεߴʑҰ͔ͭ͠ॻ͚ͳ͍ʜʜ ͦ͜ͰnewtypeʹΑΔ࣮ͷબʂ class Foldable t where foldMap :: Monoid m 㱺 (a ! m) ! t a ! m … ϞϊΠυʹม
Πϯελϯεྫ 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
Πϯελϯεྫ 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 ͷՃ๏ʹؔ͢Δ ϞϊΠυ
Πϯελϯεྫ 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 ͷՃ๏ʹؔ͢Δ ϞϊΠυ ࠷େݶʹؔ͢Δ ܈
Πϯελϯεྫ 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 ͷՃ๏ʹؔ͢Δ ϞϊΠυ ࠷େݶʹؔ͢Δ ܈ (/%ʹΑΔ ࣮ͷڞ༗
࣮ࡍ্ͷҙ w ༗քͳܕ͔͠ϞϊΠυʹͳΒͳ͍ʂʢ࠷େখݩ͕ͳ͍ͱ୯ ҐݩʹͳΒͳ͍ͷͰʣ w ୯Ґݩͷͳ͍܈ʹͳΔ w ܈͔ΒϞϊΠυʹม͠ͳ͍ͱ'PMEBCMF͑ͳ͍ʂ newtype Max a = Max a instance Ord a 㱺 Semigroup (Max a) instance Bounded a 㱺 Monoid (Max a)
࣮ࡍ্ͷҙ 0QUJPO܈ʹ୯ҐݩΛ͚ͯ͠ϞϊΠυʹ͢Δ ʙ()$ɿ.BZCF੍ͱͯ͠.POPJEBΛཁٻʂ newtype Option a = Option (Maybe a) instance Semigroup a 㱺 Monoid (Option a) instance Monoid a 㱺 Monoid (Maybe a)
࣮ࡍ্ͷҙ 0QUJPO܈ʹ୯ҐݩΛ͚ͯ͠ϞϊΠυʹ͢Δ ʙ()$ɿ.BZCF੍ͱͯ͠.POPJEBΛཁٻʂ ()$ʙɿ4FNJHSPVQBʹͳΓɺ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)
࣮ࡍ্ͷҙ 0QUJPO܈ʹ୯ҐݩΛ͚ͯ͠ϞϊΠυʹ͢Δ ʙ()$ɿ.BZCF੍ͱͯ͠.POPJEBΛཁٻʂ ()$ʙɿ4FNJHSPVQBʹͳΓɺ0QUJPOෆཁʹʂ ͱ͍͑ɺϙʔλϒϧͳίʔυΛॻ͜͏ͱࢥͬͨΒ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)
;FSP$PTU$PFSDJPO w $PFSDJCMF෦දݱ͕ಉ͡ܕಉ࢜Λؔ࿈͚ͮΔܕ੍ w ҰݟܕΫϥε͕ͩɺ࣮ࡍʹ()$͕ίϯύΠϧ࣌ʹใΛੜ ͠ɺউखʹΠϯελϯεΛՃͰ͖ͳ͍ import Data.Coerce (coerce) coerce :: Coercible a b 㱺 a ! b
;FSP$PTU$PFSDJPO w $PFSDJCMF෦දݱ͕ಉ͡ܕಉ࢜Λؔ࿈͚ͮΔܕ੍ w ҰݟܕΫϥε͕ͩɺ࣮ࡍʹ()$͕ίϯύΠϧ࣌ʹใΛੜ ͠ɺউखʹΠϯελϯεΛՃͰ͖ͳ͍ w Data.CoerceͷcoerceؔͰθϩίετͷΩϟετ͕Ͱ͖Δʂ import Data.Coerce (coerce) coerce :: Coercible a b 㱺 a ! b
;FSP$PTU$PFSDJPO w $PFSDJCMF෦දݱ͕ಉ͡ܕಉ࢜Λؔ࿈͚ͮΔܕ੍ w ҰݟܕΫϥε͕ͩɺ࣮ࡍʹ()$͕ίϯύΠϧ࣌ʹใΛੜ ͠ɺউखʹΠϯελϯεΛՃͰ͖ͳ͍ w Data.CoerceͷcoerceؔͰθϩίετͷΩϟετ͕Ͱ͖Δʂ w Ϟδϡʔϧຖʹਪɺcoerceʹσʔλߏஙࢠͷใ͕ඞཁ import Data.Coerce (coerce) coerce :: Coercible a b 㱺 a ! b
ωετܕͷม ͲΜͳίϯςφதͷܕมͰ͖ͯศརʂ ຊʹʁ newtype Down a = Down a instance Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a ٯॱΛೖΕΔ
ωετܕͷม ͲΜͳίϯςφதͷܕมͰ͖ͯศརʂ ຊʹʁ newtype Down a = Down a instance Ord a 㱺 Ord (Down a) where a ≤ b = b ≤ a data Heap a minView :: Heap a ! Maybe a ٯॱΛೖΕΔ ώʔϓ
ωετܕͷม ͲΜͳίϯςφதͷܕมͰ͖ͯศརʂ ຊʹʁ 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
ωετܕͷม ͲΜͳίϯςφதͷܕมͰ͖ͯศརʂ ຊʹʁ 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
ͦ͜Ͱ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Ͱ͋Δ͖ʂ
ͦ͜Ͱ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Ͱ͋Δ͖ʂ
ͦ͜Ͱ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ʹਪ͞ΕΔഺ
ͦ͜Ͱ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Ͱ͖ͳ͍
3PMFTৄࡉ w 3PMFʮ͜ͷܕม͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w SFQSʮ͜͜෦දݱ͕ಉ͡ͳΒಉʯ w OPNJOBMʮશʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂதʹؔͳ͠ʯ w ()$దٓ࠷ҰൠతͳSPMFΛਪͯ͘͠ΕΔ
3PMFTৄࡉ w 3PMFʮ͜ͷܕม͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w SFQSʮ͜͜෦දݱ͕ಉ͡ͳΒಉʯ w OPNJOBMʮશʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂதʹؔͳ͠ʯ w ()$దٓ࠷ҰൠతͳSPMFΛਪͯ͘͠ΕΔ w σʔλܕݻ༗ͷҙຯϢʔβ͔͠Βͳ͍ͷͰɺࠓճͷΑ ͏ͳέʔεͰϥΠϒϥϦ࣮ऀ͕ࢦఆ
3PMFTৄࡉ w 3PMFʮ͜ͷܕม͜͏͍͏ౕͰ͢ʯ w ࡾछɿrepresentational / nominal / phantom w SFQSʮ͜͜෦දݱ͕ಉ͡ͳΒಉʯ w OPNJOBMʮશʹಉ͡ܕ͡Όͳ͍ͱͩΊʯ w QIBOUPNʮλμͷ০Γʂதʹؔͳ͠ʯ w ()$దٓ࠷ҰൠతͳSPMFΛਪͯ͘͠ΕΔ w σʔλܕݻ༗ͷҙຯϢʔβ͔͠Βͳ͍ͷͰɺࠓճͷΑ ͏ͳέʔεͰϥΠϒϥϦ࣮ऀ͕ࢦఆ w OFXUZQFߏஙࢠͷใ͕ͳ͍ͱcoerceෆՄೳ
$PFSDJPO3PMFT·ͱΊ w DPFSDFؔΛ͏ͱ෦දݱͷಉ͡ܕωε τ͍ͯͯ͠θϩίετͰมՄೳ w OFXUZQFͷར༻͕ΑΓ҆શɾ؆୯ʹʂ w ࡉ͔ͳมՄೳੑ3PMFΛࢦఆ੍ͯ͠ޚ w ීஈ3PMFਪ͞ΕΔͷͰͳ͠ w ҙຯ্ม͞ΕΔͱࠔΔʗมग़དྷͯ΄͠ ͍ͷࣗͰࢦఆ
;FSP$PTU$PFSDJPOલ࢙ɿ (/%ͷड w (FOFSBMJ[FE/FXUZQF%FSJWJOH (/% ()$ ͷࠒʹطʹ͋ͬͨ w ͜ͷࠒ()$ܕγεςϜ͕߇͑Ͱɺશͯ ্ख͘ճ͍ͬͯͨ w ͦͷޙɺܕ("%5TͳͲ͕ೖΓʜʜ w ؾ͘ͱ(/%ෆ݈શʹͳ͍ͬͯͨʂ
(/%ෆ݈શ 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))
(/%ෆ݈શ 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)) (/%
(/%ෆ݈શ 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)) (/% ҙͷܕؒͷΩϟετʂ
(/%ෆ݈શ 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))
(/%ෆ݈શ 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 Λܦ༝͢ΔΑ͏ʹ
(/%ෆ݈શ 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ʹਪ
(/%ෆ݈શ 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
ྫɿ*EͷϞϊΠυߏ w લʹݟͨΑ͏ʹɺ8PSEͷϞϊΠυ࣮ෳ͋Δ w *EͰʮҰ൪৽͍͠*E ࠷େͷ*E ΛબͿʯԋࢉΛϞϊΠυԋ ࢉͱ͍͔ͯͨͬͨ͠ͱ͢Δ {-# LANGUAGE DerivingVia #-} newtype Id = MkId Word deriving (Semigroup, Monoid) via Max Word
ྫɿ*EͷϞϊΠυߏ w લʹݟͨΑ͏ʹɺ8PSEͷϞϊΠυ࣮ෳ͋Δ w *EͰʮҰ൪৽͍͠*E ࠷େͷ*E ΛબͿʯԋࢉΛϞϊΠυԋ ࢉͱ͍͔ͯͨͬͨ͠ͱ͢Δ w Max WordIdͱಉҰදݱɺ NBY
ʹؔ͠ϞϊΠυ {-# LANGUAGE DerivingVia #-} newtype Id = MkId Word deriving (Semigroup, Monoid) via Max Word
ྫɿ*EͷϞϊΠυߏ w લʹݟͨΑ͏ʹɺ8PSEͷϞϊΠυ࣮ෳ͋Δ w *EͰʮҰ൪৽͍͠*E ࠷େͷ*E ΛબͿʯԋࢉΛϞϊΠυԋ ࢉͱ͍͔ͯͨͬͨ͠ͱ͢Δ w Max WordIdͱಉҰදݱɺ NBY
ʹؔ͠ϞϊΠυ w %FSJWJOH7JB͜ͷ࣮Λࣗಈతʹ*Eʹ্࣋ͪ͛ͯ͘ΕΔʂ {-# LANGUAGE DerivingVia #-} newtype Id = MkId Word deriving (Semigroup, Monoid) via Max Word
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
·ͱΊ w OFXUZQFͷ༻్ࡾͭ w ࣮ͷӅṭʗ࣮ͷڞ༗ʗ࣮ͷબ w %BUB$PFSDFΛ͏ͱ෦දݱ͕ಉ͡ܕಉ࢜Λθϩ ίετͰΩϟετՄೳ w OFXUZQFͷग़ੈ͔͜͜Β࢝·ͬͨ w ෳ߹ܕ3PMFਪɾḼऍͰదʹѻ͑Δ w ()$͔Β%FSJWJOH7JBͰOFXUZQFʹΑΓ ಋग़અΛΧελϚΠζՄೳʹʂ
ࢀߟจݙ 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.
"OZ2VFTUJPO w OFXUZQFͷ༻్ࡾͭ w ࣮ͷӅṭʗ࣮ͷڞ༗ʗ࣮ͷબ w %BUB$PFSDFΛ͏ͱ෦දݱ͕ಉ͡ܕಉ࢜Λθϩ ίετͰΩϟετՄೳ w OFXUZQFͷग़ੈ͔͜͜Β࢝·ͬͨ w ෳ߹ܕ3PMFਪɾḼऍͰదʹѻ͑Δ w ()$͔Β%FSJWJOH7JBͰOFXUZQFʹΑΓ ಋग़અΛΧελϚΠζՄೳʹʂ
7 ↵ M ↵ ' [ · ] 9! 7QH/JT ' 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 ࣗ༝Ϟφυͷීวੑ w ࣗ༝ϞϊΠυവखͷఆ͔ٛΒ w α͔ΒGαͷೖࣹ w G͕വखͰ͋Δ͜ͱ w Gα͕ࣗϞϊΠυͰ͋Δࣄ w ʜʜΛআ͘ͱ'PMEBCMFʹͳΔ w ࡞Δํ๏͕ͳ͍͍ͯ͘ w Hask ݍͷവखͱݶΒͳ͍ w ϞϊΠυͱݶΒͳ͍ɺ୯ͳΔ ߏͰΈࠐΈ͍ͨ
'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