องค์ประกอบของฟังก์ชัน Haskell (.) และฟังก์ชันของแอปพลิเคชัน ($) สำนวน: การใช้ที่ถูกต้อง


129

ผมได้อ่านโลกแห่งความจริง Haskellและฉันกำลังใกล้จะจบ แต่เรื่องของรูปแบบที่ได้รับการ niggling ที่ผมจะทำอย่างไรกับ(.)และ($)ผู้ประกอบการ

เมื่อคุณเขียนฟังก์ชั่นที่เป็นองค์ประกอบของฟังก์ชั่นอื่น ๆ ที่คุณเขียนมันชอบ:

f = g . h

แต่เมื่อคุณใช้บางสิ่งกับท้ายฟังก์ชั่นเหล่านั้นฉันเขียนมันแบบนี้

k = a $ b $ c $ value

แต่หนังสือจะเขียนดังนี้:

k = a . b . c $ value

ตอนนี้สำหรับฉันแล้วพวกเขาดูมีประโยชน์เทียบเท่าพวกเขาทำสิ่งเดียวกันในสายตาของฉัน อย่างไรก็ตามยิ่งฉันดูมากเท่าไหร่ฉันก็ยิ่งเห็นคนเขียนหน้าที่ของตนมากขึ้นในลักษณะที่หนังสือเล่มนี้เขียนขึ้นด้วย(.)อันดับแรกและสุดท้ายเท่านั้นที่($)จะใช้เพื่อผนวกค่าเพื่อประเมินจำนวนมาก .

มีเหตุผลในการใช้วิธีหนังสือที่ดีกว่าการใช้($)สัญลักษณ์ทั้งหมดหรือไม่ หรือมีแนวปฏิบัติที่ดีที่สุดที่ฉันไม่ได้รับบ้าง หรือมันฟุ่มเฟือยและฉันไม่ควรกังวลเกี่ยวกับเรื่องนี้เลย?


4
โปรดทราบว่าตัวอย่างที่สองสามารถทำได้ดังนี้k = a $ b $ c value
Thomas Eding

1
ใช่มันทำได้ดังที่ Zifre กล่าวไว้ด้านล่าง แต่ฉันตัดสินใจที่จะออกจากที่นั่นเพราะมันไม่ได้ทำอันตรายอะไรเลยและทำให้ความเห็นของเขา (และตอนนี้) ของคุณสมเหตุสมผล ขอบคุณแม้ว่า +1 :)
Robert Massaioli

2
วิธีการทั่วไปอีกอย่างหนึ่งคือa . b $ c valueฉันไม่ชอบตัวอย่างที่สามมากนัก แต่ช่วยประหยัดอักขระได้เล็กน้อย
John L

คำตอบ:


153

ฉันเดาว่าฉันสามารถตอบคำถามนี้จากผู้มีอำนาจ

มีเหตุผลในการใช้วิธีหนังสือที่ดีกว่าการใช้สัญลักษณ์ ($) ทั้งหมดหรือไม่

ไม่มีเหตุผลพิเศษ ไบรอันและฉันต่างก็ชอบลดเสียงรบกวนของสาย เป็นที่เงียบสงบกว่า. $เป็นผลให้หนังสือใช้f . g . h $ xไวยากรณ์


3
ฉันไม่หวังว่าจะได้คำตอบที่ดีไปกว่านี้ จากหนึ่งในผู้แต่งเอง :) และมันก็สมเหตุสมผลดีมันดูเงียบกว่าตอนที่ฉันอ่าน การทำเครื่องหมายว่านี่เป็นคำตอบเพราะมันจะตอบคำถามโดยตรง ขอบคุณสำหรับคำตอบ และ infact หนังสือ
Robert Massaioli

38
ไม่เห็นด้วยกับผู้เขียน แต่ฉันคิดว่ามีอีกเหตุผลที่โดดเด่นมากกว่าในรูปแบบทางจิตของการสร้างบางสิ่งมากกว่าที่จะใช้มัน ผู้ใช้ Haskell มักจะคิดว่าf.g.hเป็นการสร้างที่ฉลาดf(g(h()))กว่า ตอนนี้พวกเขากำลังเรียกฟังก์ชั่นใหม่ที่ไม่ระบุชื่อแม้ว่าพวกเขาจะสร้างขึ้นแทนที่จะเพียงผูกมัดพจนานุกรมขนาดใหญ่ของฟังก์ชั่น prefabbed การโทรเช่นผู้ใช้ PHP
Evan Carroll

1
นั่นเป็นคำที่น่าสนใจ: 'ลดเสียงรบกวนของเส้น' และ 'เงียบกว่า' ฉันไม่เคยคิดถึงการเขียนโปรแกรมภาษาในคำศัพท์นี้ แต่มันสมเหตุสมผลดี
Rabarberski

53

พวกเขาจะเทียบเท่าจริง ๆ : โปรดจำไว้ว่า$ผู้ปฏิบัติงานทำอะไรเป็นหลัก ประเมินf $ x f xวัตถุประสงค์ของการ$เป็นพฤติกรรม fixity: ขวาเชื่อมโยงและความสำคัญน้อยที่สุด การลบ$และการใช้วงเล็บสำหรับการจัดกลุ่มแทนการใส่ลำดับความสำคัญของโค้ดโค้ดจะมีลักษณะดังนี้:

k = a (b (c (value)))

และ

k = (a . b . c) value

เหตุผลในการเลือก.รุ่นที่มากกว่า$รุ่นเดียวกันนั้นเป็นเหตุผลเดียวกันในการเลือกทั้งเวอร์ชั่นที่อยู่ในวงเล็บด้านบน: ความสวยงาม

แม้ว่าบางคนอาจสงสัยว่าการใช้ตัวดำเนินการมัดแทนวงเล็บจะขึ้นอยู่กับการกระตุ้นจิตใต้สำนึกบางอย่างเพื่อหลีกเลี่ยงความคล้ายคลึงกับ Lisp (อาจล้อเล่น ... ฉันคิดว่า?)


38

ฉันต้องการเพิ่มในการที่f . g $ x, f . gเป็นหน่วยประโยคที่มีความหมาย

ในขณะเดียวกันในf $ g $ x, f $ gไม่ได้เป็นหน่วยที่มีความหมาย ห่วงโซ่ของการ$เป็น arguably ความจำเป็นมากขึ้น - ครั้งแรกที่ได้รับผลจากgการx, แล้วทำfไปแล้วจะทำอย่างไรfooกับมันแล้วฯลฯ

ในขณะที่สายโซ่ของ.การประกาศเนื้อหาเพิ่มเติมและในบางแง่มุมใกล้กับมุมมองเป็นศูนย์กลาง dataflow - เขียนชุดของฟังก์ชั่นและในที่สุดนำไปใช้กับบางสิ่งบางอย่าง


2
ฉันกำลังเรียนรู้ Haskell (ไม่ได้เขียนโค้ดอะไรที่มีความหมาย) แต่ฉันชอบคิดว่า $ เป็นตัวดำเนินการ "ไปป์" มันมากเหมือนขั้ว | ไพพ์ (ยกเว้นข้อมูลไหลจากขวาไปซ้าย) แต่ก็เหมือนกับกระบวนการเทอร์มินัลแต่ละหน่วยมีความเป็นอิสระอย่างชัดเจน
LostSalad

1
$ประกอบดูเหมือนว่าจะมีพฤติกรรมคล้ายกับ<|ผู้ประกอบการใน F # ฉันเชื่อว่าทั้งสองถูกกำหนดเหมือนกันในความเป็นจริง - ใน F # (<|) a b = a bและใน Haskell a $ b = a bซึ่งเทียบเท่าโดยพื้นฐานแล้ว
Tom Galvin

@Quackmatic ค่อนข้างมั่นใจว่ามัน(<|) b a = a bอยู่ใน F # เนื่องจากใช้เหมือน[1; 2; 3; 4; 5] <| List.map ((+) 1)ถ้าหน่วยความจำทำหน้าที่
BalinKingOfMoria คืนค่า CM ใหม่

@BalinKingOfMoria ตัว<|ดำเนินการส่งผ่านค่าไปยังฟังก์ชันแทนที่จะส่งผ่านฟังก์ชันไปยังค่า - ตัวอย่างรหัสของคุณจะทำงานกับตัว|>ดำเนินการแทน
Tom Galvin

@Quackmatic โอ้ ไม่ทราบว่ามีหลายเวอร์ชัน (ฉันไม่ได้ใช้ F # มาก)
BalinKingOfMoria คืนค่า CM อีกครั้งใน

18

สำหรับผมผมคิดว่าคำตอบคือ (ก) ความเรียบร้อยเช่นดอนกล่าวว่า ; และ (b) ฉันพบว่าเมื่อฉันแก้ไขโค้ดฟังก์ชันของฉันอาจสิ้นสุดในรูปแบบที่ไม่มีจุดและจากนั้นสิ่งที่ฉันต้องทำคือลบอันสุดท้าย$แทนที่จะกลับไปเปลี่ยนทุกอย่าง จุดเล็ก ๆ น้อย ๆ อย่างแน่นอน แต่ความดี


ใช่นั่นเป็นเหตุผลที่ดีที่จะเขียนมันอย่างนั้นถ้าคุณต้องการที่จะจบในการจัดองค์ประกอบฟังก์ชั่นแล้วมันจะเร็วขึ้น :) Yay สำหรับการบันทึกการกดแป้น แต่เวลาสำคัญกว่า +1
Robert Massaioli

13

มีการสนทนาที่น่าสนใจของคำถามนี้ในเธรด haskell-cafeนี้ เห็นได้ชัดว่ามีมุมมองที่เป็นชนกลุ่มน้อยที่ถือได้ว่าการเชื่อมโยงกันทางขวาของ$คือ"ผิดธรรมดาเพียง"และเลือกf . g . h $ xมากกว่าf $ g $ h $ xเป็นวิธีหนึ่งในด้านก้าวปัญหา


เฮ้คุณพบการสนทนาทั้งหมดในเรื่องนี้ มันเยี่ยมมากฉันอ่านตอนนี้ +1
Robert Massaioli

2
ข้อโต้แย้งที่คล้ายกันที่นี่: ghc.haskell.org/trac/haskell-prime/wiki/…
enrique

โปรดทราบว่า$!ยังมีการเชื่อมโยงที่ถูกต้อง "ผิดธรรมดา" - ทำไมจึงเป็น $! ผู้ประกอบการขวาสัมพันธ์? .
imz - Ivan Zakharyaschev

3

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

วิธีการของคุณดูแปลก ๆ และสุดท้าย$ก็ไม่จำเป็น

อย่างไรก็ตามมันไม่สำคัญ ใน Haskell มักจะมีวิธีที่ถูกต้องมากมายที่จะทำสิ่งเดียวกัน


3
ฉันไม่ได้สังเกตเห็นว่า $ สุดท้ายไม่จำเป็น แต่ฉันควรจะมี ขอบคุณและฉันจะทิ้งไว้ที่นั่นเพื่อให้ผู้คนรู้ว่าความคิดเห็นนี้หมายถึงอะไร
Robert Massaioli

0

ฉันรู้ว่านี่เป็นคำถามที่เก่ามาก แต่ฉันคิดว่ามีเหตุผลอื่นที่ไม่ได้กล่าวถึง

หากคุณกำลังประกาศฟังก์ชั่นที่ไม่มีจุดใหม่f . g . hค่าที่คุณส่งผ่านจะถูกนำไปใช้โดยอัตโนมัติ อย่างไรก็ตามถ้าคุณเขียน f $ g $ hมันจะไม่ทำงาน

ฉันคิดว่าเหตุผลที่ผู้เขียนชอบวิธีการจัดวางเพราะมันนำไปสู่การฝึกฝนการสร้างฟังก์ชั่นที่ดี

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