Applicativetypeclass หมายถึงหละหลวม monoidal functors ที่รักษาโครงสร้าง monoidal คาร์ทีเซียนในหมวดหมู่ของฟังก์ชั่นพิมพ์
กล่าวอีกนัยหนึ่งได้รับ isomorphisms บัญญัติซึ่ง(,)เป็นรูปแบบโครงสร้าง monoidal:
-- Implementations left to the motivated reader
assoc_fwd :: ((a, b), c) -> (a, (b, c))
assoc_bwd :: (a, (b, c)) -> ((a, b), c)
lunit_fwd :: ((), a) -> a
lunit_bwd :: a -> ((), a)
runit_fwd :: (a, ()) -> a
runit_bwd :: a -> (a, ())
typeclass และกฎหมายของมันสามารถเขียนแบบนี้ได้:
class Functor f => Applicative f
where
zip :: (f a, f b) -> f (a, b)
husk :: () -> f ()
-- Laws:
-- assoc_fwd >>> bimap id zip >>> zip
-- =
-- bimap zip id >>> zip >>> fmap assoc_fwd
-- lunit_fwd
-- =
-- bimap husk id >>> zip >>> fmap lunit_fwd
-- runit_fwd
-- =
-- bimap id husk >>> zip >>> fmap runit_fwd
บางคนอาจสงสัยว่าสิ่งที่นักแสดงที่oplax monoidal เกี่ยวกับโครงสร้างเดียวกันอาจมีลักษณะ:
class Functor f => OpApplicative f
where
unzip :: f (a, b) -> (f a, f b)
unhusk :: f () -> ()
-- Laws:
-- assoc_bwd <<< bimap id unzip <<< unzip
-- =
-- bimap unzip id <<< unzip <<< fmap assoc_bwd
-- lunit_bwd
-- =
-- bimap unhusk id <<< unzip <<< fmap lunit_bwd
-- runit_bwd
-- =
-- bimap id unhusk <<< unzip <<< fmap runit_bwd
หากเรานึกถึงประเภทที่เกี่ยวข้องกับคำจำกัดความและกฎหมายความจริงที่น่าผิดหวังจะถูกเปิดเผย OpApplicativeไม่มีข้อ จำกัด เจาะจงกว่าFunctor:
instance Functor f => OpApplicative f
where
unzip fab = (fst <$> fab, snd <$> fab)
unhusk = const ()
อย่างไรก็ตามในขณะที่Applicativefunctor ทุกคน(จริง ๆFunctor) OpApplicativeมีความสำคัญไม่จำเป็นต้องมีความสัมพันธ์ที่ดีระหว่างApplicativelaxities และOpApplicativeoplaxities ดังนั้นเราสามารถมองหาฟังก์ชั่นที่แข็งแกร่ง monoidal wrt โครงสร้าง monoidal คาร์ทีเซียน:
class (Applicative f, OpApplicative f) => StrongApplicative f
-- Laws:
-- unhusk . husk = id
-- husk . unhusk = id
-- zip . unzip = id
-- unzip . zip = id
กฎหมายข้างต้นเป็นครั้งแรกเล็กน้อยเนื่องจากเพียงอาศัยของชนิดเป็นฟังก์ชั่นในตัวตน() -> ()()
อย่างไรก็ตามกฎสามข้อที่เหลืออยู่และด้วยเหตุนี้คลาสย่อยเองจึงไม่ใช่เรื่องเล็กน้อย โดยเฉพาะไม่ทุกคนApplicativeเป็นตัวอย่างที่ถูกต้องตามกฎหมายของชั้นนี้
นี่คือฟังก์ชั่นบางอย่างApplicativeที่เราสามารถประกาศอินสแตนซ์ที่ถูกกฎหมายของStrongApplicative:
IdentityVoidF(->) r(ดูคำตอบ)Monoid m => (,) mVec (n :: Nat)Stream(อนันต์)
และนี่คือบางส่วนApplicativeที่เราไม่สามารถ:
[]Either eMaybeNonEmptyList
รูปแบบที่นี่แสดงให้เห็นว่าStrongApplicativeระดับอยู่ในความรู้สึกที่FixedSizeระดับที่ "ขนาดคงที่" *หมายความว่าหลายหลาก**ของชาวaในที่อยู่อาศัยของf aการแก้ไข
สิ่งนี้สามารถกล่าวได้ว่าเป็นสองการคาดเดา:
- ทุกคนที่
Applicativeเป็นตัวแทนของภาชนะ "ขนาดคงที่" ขององค์ประกอบของการโต้แย้งประเภทของมันเป็นตัวอย่างของStrongApplicative - ไม่มีอินสแตนซ์ที่
StrongApplicativeมีจำนวนครั้งของการเกิดขึ้นซึ่งaแตกต่างกันไป
ทุกคนสามารถนึกถึงตัวอย่างที่หักล้างการคาดเดาเหล่านี้หรือเหตุผลที่น่าเชื่อถือบางอย่างที่แสดงให้เห็นว่าทำไมพวกเขาถึงเป็นจริงหรือเท็จ?
* ฉันรู้ว่าฉันยังไม่ได้กำหนดคำคุณศัพท์ "ขนาดคงที่" อย่างถูกต้อง น่าเสียดายที่งานมีลักษณะกลมเล็กน้อย ฉันไม่รู้คำอธิบายที่เป็นทางการของคอนเทนเนอร์ "ขนาดคงที่" และฉันพยายามหาที่มา StrongApplicativeเป็นความพยายามที่ดีที่สุดของฉันจนถึงตอนนี้
เพื่อที่จะประเมินว่านี่เป็นคำจำกัดความที่ดี แต่ฉันต้องการบางสิ่งบางอย่างเพื่อเปรียบเทียบ ให้คำจำกัดความที่เป็นทางการ / ไม่เป็นทางการว่ามันหมายถึงอะไรสำหรับนักแสดงที่จะมีขนาดหรือหลายหลากด้วยความเคารพต่อชาวอาร์กิวเมนต์ประเภทคำถามที่ว่าการดำรงอยู่ของStrongApplicativeอินสแตนซ์ที่แตกต่างกันอย่างชัดเจน
ไม่ได้ตระหนักถึงคำจำกัดความที่เป็นทางการที่มีอยู่ฉันกำลังขอร้องให้สัญชาตญาณในการใช้คำว่า "ขนาดคงที่" อย่างไรก็ตามถ้ามีคนรู้อยู่แล้วเกี่ยวกับพิธีการที่มีอยู่สำหรับขนาดของนักแสดงและสามารถเปรียบเทียบStrongApplicativeกับมันได้ดีกว่ามาก
** โดย "พหุคูณ" ฉันหมายถึงองค์ประกอบหลวม ๆ ของประเภทพารามิเตอร์ของ functor ที่เกิดขึ้นในผู้อยู่อาศัยประเภทรหัสของ functor นี่คือโดยไม่คำนึงถึงประเภทเฉพาะที่ functor ถูกนำไปใช้และด้วยเหตุนี้โดยไม่คำนึงถึงผู้อยู่อาศัยที่เฉพาะเจาะจงของประเภทพารามิเตอร์
การที่ไม่แม่นยำเกี่ยวกับเรื่องนี้ทำให้เกิดความสับสนในความเห็นดังนั้นนี่คือตัวอย่างของสิ่งที่ฉันจะพิจารณาขนาด / หลายหลากของฟังก์ชั่นต่างๆเป็น:
VoidF: แก้ไขแล้ว 0Identity: แก้ไขแล้ว 1Maybe: ตัวแปรขั้นต่ำ 0 สูงสุด 1[]: ตัวแปร 0 ต่ำสุดสูงสุดไม่ จำกัดNonEmptyList: ตัวแปรขั้นต่ำ 1 สูงสุดไม่ จำกัดStream: แก้ไขไม่มีที่สิ้นสุดMonoid m => (,) m: แก้ไขแล้ว 1data Pair a = Pair a a: แก้ไขแล้ว 2Either x: ตัวแปรขั้นต่ำ 0 สูงสุด 1data Strange a = L a | R a: แก้ไขแล้ว 1
(->) rมันคือ isomorphic ในแบบที่ถูกต้อง
(->) r; คุณต้องการส่วนประกอบของ isomorphism เพื่อรักษาโครงสร้างการใช้งานที่แข็งแกร่ง ด้วยเหตุผลบางอย่างRepresentable typeclass ใน Haskell มีtabulate . return = returnกฎหมายลึกลับ(ซึ่งไม่ได้ใช้กับผู้ที่ไม่ใช่ monadic functors) แต่มันทำให้เรามี 1/4 ของเงื่อนไขที่เราจำเป็นต้องพูดtabulateและzipเป็น morphisms ของ monoids ประเภทที่เหมาะสม . อีก 3 ข้อเป็นกฎหมายเพิ่มเติมที่คุณต้องเรียกร้อง
tabulateและindexเป็น morphisms ของหมวดหมู่ที่เหมาะสม ... "
returnไม่ใช่ปัญหาร้ายแรง cotraverse getConst . Constเป็นการใช้งานเริ่มต้นสำหรับreturn/ pureในแง่ของDistributiveและเนื่องจากตัวแทนจำหน่าย / Representables มีรูปร่างคงที่การใช้งานนั้นไม่ซ้ำกัน