Tuple เพิ่มเติมใน pointfree


16

เป็นวิธีที่สั้นที่สุดที่เราสามารถแสดงฟังก์ชั่นอะไร

f(a,b)(c,d)=(a+c,b+d)

ในสัญกรณ์ฟรี

pointfree.ioให้เรา

uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))

ซึ่งสามารถทำงานให้สั้นลงได้

uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)

สำหรับ 76 ไบต์ แต่ตอนนี้ยังดูเหมือนว่ามันยาวและซับซ้อนสำหรับการดังกล่าวเป็นงานที่ง่าย มีวิธีใดบ้างที่เราสามารถแสดงการเพิ่มขึ้นของจำนวนคู่ในฐานะฟังก์ชั่นไร้จุดที่สั้นกว่าได้หรือไม่?

เพื่อให้ชัดเจนโดยสิ่งที่ฉันหมายถึงโดยไม่มีจุดการประกาศจุดของฟังก์ชั่นที่เกี่ยวข้องกับการมีฟังก์ชั่นที่มีอยู่และผู้ประกอบการและใช้พวกเขากับแต่ละอื่น ๆ ในลักษณะที่ฟังก์ชั่นที่ต้องการจะถูกสร้างขึ้น backticks วงเล็บและคุณค่าที่แท้จริง ( [], 0, [1..3]ฯลฯ ) จะได้รับอนุญาต แต่คำหลักเช่นwhereและletจะไม่ หมายความว่า:

  • คุณไม่สามารถกำหนดตัวแปร / ฟังก์ชั่นใด ๆ

  • คุณไม่สามารถใช้ lambdas

  • คุณไม่สามารถนำเข้า

นี่เป็นคำถามเดียวกันเมื่อเป็น CMC


9
ฉันไม่เคยเข้าใจว่าทำไมเรียกว่า " ปราศจากจุด" เมื่อมันเต็มไปด้วยจุด : P
Mr. Xcoder


5
มันเป็นความอัปยศที่เราไม่ได้รับอนุญาตให้นำเข้าแพ็คเกจ Haskell ที่ดีที่สุดไม่เช่นนั้นโซลูชันก็จะเป็น(+)***(+)เช่นนั้น
Silvio Mayolo

2
ความคิด: จะช่วยให้(+)<$>([1],2)<*>([3],4) ([1,3],6)
xnor

2
ฉันใช้เวลาพยายามประดิษฐ์ทางออกที่ดีโดยใช้ปลายของ xnor ... แต่ฉันก็ทิ้งขยะนี้ ฉันไม่รู้ด้วยซ้ำว่าทำไมบางครั้งฉันถึงต้องลอง ...
สิ้นเชิงมนุษย์

คำตอบ:



8

44 ไบต์

-8 ไบต์ขอบคุณØrjan Johansen -3 ไบต์ขอบคุณ Bruce Forte

(.).flip(.)<*>(zipWith(+).)$mapM id[fst,snd]

ลองออนไลน์!

แปลเป็น:

f t1 t2 = zipWith (+) (mapM id [fst, snd] $ t1) (mapM id [fst, snd] $ t2)

67 ไบต์

-8 ไบต์ขอบคุณØrjan Johansen -1 ไบต์ต้องขอบคุณ Bruce Forte

หากต้องการเอาต์พุต tuple:

(((,).head<*>last).).((.).flip(.)<*>(zipWith(+).)$mapM id[fst,snd])

ลองออนไลน์!

ใช่ฉันทำเองไม่ได้ผลสุก แต่ฉันมีความสุขกับการ[a] → (a, a)กลับใจใหม่

listToPair  [a]  (a, a)
listToPair = (,) . head <*> last
-- listToPair [a, b] = (a, b)

ตอนนี้ถ้ามีความสั้นm (a → b) → a → m bฟังก์ชั่น


3
เกลียดที่จะทำลายมันให้กับคุณ แต่mapM id[fst,snd]จะสั้นกว่า
Ørjan Johansen

น่าเศร้าที่mapM idเป็นแข็งแรงเล่นกอล์ฟsequenceรุ่นของฟังก์ชั่นที่คุณอาจกำลังมองหา
Ørjan Johansen

ใช่นั่นเป็นความจริง. ฉันแค่มองไปที่(<*>)ลายเซ็น 's m (a → b) → m a → m bซึ่งเป็น ใกล้แล้ว ...
มนุษย์ทั้งหมด

1
นอกจากนี้ยังมีControl.Lens.??ซึ่งอาจมีการเสนอให้รวมอยู่ในฐานในบางจุด
Ørjan Johansen

ฉันต้องการแยกสิ่งที่ซ้ำ(.mapM id[fst,snd])กันlet r=(.mapM id[fst,snd]) in r(r.zipWith(+))ออกไป แต่ฉันไม่สามารถรับตัวตรวจสอบชนิดเพื่อยอมรับรุ่นที่ไม่มีจุดหมาย
xnor

4

54 ไบต์

ฉันสงสัยอย่างตรงไปตรงมาว่าเราจะเอาชนะโซลูชัน 44 ไบต์ของ @H.PWiz แต่ไม่มีใครใช้ความจริงที่(,)ใช้คลาสประเภทFunctorดังนั้นนี่เป็นอีกสิ่งที่น่าสนใจซึ่งไม่เลวเกินไป:

((<*>snd).((,).).(.fst).(+).fst<*>).flip(fmap.(+).snd)

ลองออนไลน์!

คำอธิบาย

การใช้งานคลาสประเภทFunctorสำหรับ2 -Tuples นั้นคล้ายกับของEither(จากbase-4.10.1.0 ):

instance Functor ((,) a) where
    fmap f (x,y) = (x, f y)

instance Functor (Either a) where
    fmap _ (Left x) = Left x
    fmap f (Right y) = Right (f y)

สิ่งนี้หมายความว่าอย่างไรสำหรับความท้าทายนี้คือฟังก์ชั่นต่อไปนี้จะเพิ่มองค์ประกอบที่สองในขณะที่รักษาองค์ประกอบแรกของอาร์กิวเมนต์ที่สอง:

λ f = fmap.(+).snd :: Num a => (a, a) -> (a, a) -> (a, a)
λ f (1,-2) (3,-4)
(3,-6)

ดังนั้นถ้าเรามีผู้ช่วยตัวน้อยhelpPlz = \a b -> (fst a+fst b,snd b)เราก็สามารถทำได้(helpPlz<*>).flip(fmap.(+).snd)และจะทำ โชคดีที่เรามีเครื่องมือpointfreeที่ให้:

helpPlz = (`ap` snd) . ((,) .) . (. fst) . (+) . fst

ดังนั้นเพียงแค่เสียบฟังก์ชั่นนั้นกลับเข้ามาเราก็จะมาถึงวิธีการแก้ปัญหาข้างต้น (โปรดสังเกตว่า(<*>) = apสิ่งใดที่อยู่ในฐาน )


4

60 ไบต์

ฉันไม่เห็นความuncurryรักใด ๆที่นี่ดังนั้นฉันจึงคิดว่าฉันจะเข้ามาและแก้ไขสิ่งนั้น

uncurry$(uncurry.).flip(.)(flip(.).(+)).(flip(.).((,).).(+))

ฉันคิดว่าด้วยทั้งหมดfstและsndที่เปิดออกอาร์กิวเมนต์ด้วยuncurryอาจให้ผลลัพธ์บางอย่าง เห็นได้ชัดว่ามันไม่เกิดผลอย่างที่ฉันหวังไว้


2
uncurryเป็น verbose ดังนั้น :( แต่คุณสามารถแทนที่วงเล็บที่อยู่ด้านนอกสุด$ได้
Ørjan Johansen

ใช่และน่าเสียดายที่มีปัญหากับชื่อฟังก์ชันจำนวนมากใน Haskell นานเกินไปสำหรับการเล่นกอล์ฟ แต่ขอบคุณสำหรับการออม 1 ตัวละคร!
Silvio Mayolo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.