Applicative
typeclass หมายถึงหละหลวม 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 ()
อย่างไรก็ตามในขณะที่Applicative
functor ทุกคน(จริง ๆFunctor
) OpApplicative
มีความสำคัญไม่จำเป็นต้องมีความสัมพันธ์ที่ดีระหว่างApplicative
laxities และOpApplicative
oplaxities ดังนั้นเราสามารถมองหาฟังก์ชั่นที่แข็งแกร่ง 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
:
Identity
VoidF
(->) r
(ดูคำตอบ)Monoid m => (,) m
Vec (n :: Nat)
Stream
(อนันต์)
และนี่คือบางส่วนApplicative
ที่เราไม่สามารถ:
[]
Either e
Maybe
NonEmptyList
รูปแบบที่นี่แสดงให้เห็นว่า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 มีรูปร่างคงที่การใช้งานนั้นไม่ซ้ำกัน