เทมเพลตแฮสเค็ลมีอะไรเลวร้าย


252

ดูเหมือนว่าแม่แบบ Haskell มักถูกมองโดยชุมชน Haskell ว่าเป็นความสะดวกสบายที่โชคร้าย เป็นการยากที่จะพูดออกมาอย่างชัดเจนถึงสิ่งที่ฉันสังเกตเห็นในเรื่องนี้ แต่พิจารณาตัวอย่างเล็ก ๆ น้อย ๆ เหล่านี้

ฉันได้เห็นโพสต์บล็อกต่าง ๆ ที่ผู้คนทำสิ่งต่าง ๆ เรียบร้อยด้วยเทมเพลตแฮสเค็ลล์ทำให้เปิดใช้งานไวยากรณ์ที่สวยกว่าซึ่งไม่สามารถทำได้ในแฮสเค็ลล์ปกติ ดังนั้นทำไมเทมเพลตแฮสเคลล์จึงถูกมองลงไปด้วยวิธีนี้? อะไรทำให้ไม่พึงปรารถนา เทมเพลต Haskell ควรหลีกเลี่ยงสถานการณ์ใดและเพราะอะไร


56
ฉันไม่เห็นด้วยกับการลงคะแนนให้ย้าย; ฉันถามคำถามนี้ด้วยจิตวิญญาณเดียวกันกับที่ฉันถามว่ามีอะไรไม่ดีเกี่ยวกับ Lazy I / O? และฉันคาดหวังว่าจะเห็นคำตอบของแฟชั่นแบบเดียวกัน ฉันเปิดให้มีการตอบคำถามใหม่หากจะช่วยได้
Dan Burton

51
@ErikPhilips ทำไมคุณไม่ให้คนที่แท็กนี้บ่อยตัดสินใจว่าเป็นของที่นี่หรือไม่ ดูเหมือนว่าคุณจะมีปฏิสัมพันธ์กับชุมชน Haskell เพียงอย่างเดียวคือการตั้งคำถาม
Gabriel Gonzalez

5
@GabrielGonzalez มันเห็นได้ชัดด้วยคำถามในปัจจุบันและคำตอบว่ามันไม่ได้เป็นไปตามคำถามที่พบบ่อยภายใต้สิ่งที่ชนิดของคำถามที่ฉันไม่ควรถามที่นี่: ไม่มีปัญหาที่เกิดขึ้นจริงที่จะแก้ไข คำถามไม่มีการแก้ปัญหาเฉพาะรหัสและเป็นเพียงแนวคิดในลักษณะ และขึ้นอยู่กับคำถามที่ฉันควรหลีกเลี่ยงการ Haskell แม่แบบมากเกินไปมันตกอยู่ในกองมากเกินไม่ได้เป็นเครื่องยนต์แนะนำ
Erik Philips

27
@ErikPhilips ส่วนเครื่องมือการแนะนำนั้นไม่เกี่ยวข้องกับคำถามนี้เนื่องจากคุณจะสังเกตเห็นว่าการอ้างถึงการตัดสินใจระหว่างเครื่องมือต่าง ๆ (เช่น "บอกฉันว่าฉันควรใช้ภาษาใด") ในทางตรงกันข้ามฉันแค่ขอคำอธิบายเกี่ยวกับเทมเพลตแฮสเค็ลล์โดยเฉพาะและคำถามที่พบบ่อยระบุว่า "ถ้าแรงจูงใจของคุณคือ" ฉันต้องการให้คนอื่นอธิบาย [ว่าง] กับฉัน "จากนั้นคุณก็โอเค เปรียบเทียบกับตัวอย่างเช่นGOTO ยังถือว่าเป็นอันตรายหรือไม่
Dan Burton

29
การลงคะแนนเพื่อเปิดใหม่ เพียงเพราะเป็นคำถามระดับที่สูงขึ้นไม่ได้หมายความว่าไม่ใช่คำถามที่ดี
György Andrasek

คำตอบ:


171

เหตุผลหนึ่งในการหลีกเลี่ยงเทมเพลตแฮสเค็ลล์ก็คือโดยรวมแล้วไม่ปลอดภัยสำหรับทุกคนดังนั้นจะต่อต้าน "จิตวิญญาณของแฮสเค็ล" มาก นี่คือตัวอย่างบางส่วนของสิ่งนี้:

  • คุณไม่สามารถควบคุมประเภทของรหัส Haskell AST ที่จะสร้างขึ้นได้นอกเหนือไปจากที่จะปรากฏ คุณสามารถมีค่าเป็นประเภทExpแต่คุณไม่รู้ว่ามันเป็นนิพจน์ที่แสดงถึง[Char]หรือ(a -> (forall b . b -> c))หรืออะไรก็ตาม TH จะมีความน่าเชื่อถือมากขึ้นถ้าใครสามารถแสดงออกได้ว่าฟังก์ชั่นอาจสร้างการแสดงออกของบางประเภทหรือการประกาศฟังก์ชั่นเท่านั้นหรือเพียงรูปแบบการจับคู่ข้อมูล - คอนสตรัคเตอร์ ฯลฯ
  • คุณสามารถสร้างการแสดงออกที่ไม่ได้รวบรวม คุณสร้างนิพจน์ที่อ้างอิงถึงตัวแปรอิสระfooที่ไม่มีอยู่จริงหรือไม่? โชคดีที่คุณจะเห็นว่าเมื่อใช้ตัวสร้างโค้ดจริง ๆ และในสถานการณ์ที่ก่อให้เกิดการสร้างรหัสนั้นขึ้นมาเท่านั้น การทดสอบหน่วยก็เป็นเรื่องยากเช่นกัน

TH ก็อันตรายทันทีเช่นกัน:

  • รหัสที่ทำงานในเวลารวบรวมสามารถทำได้ตามอำเภอใจIOรวมถึงการเปิดตัวขีปนาวุธหรือขโมยบัตรเครดิตของคุณ คุณไม่ต้องการค้นหาแพคเกจ cabal ทุกครั้งที่คุณดาวน์โหลดเพื่อค้นหาช่องโหว่ของ TH
  • TH สามารถเข้าถึงฟังก์ชั่นและคำจำกัดความของ "โมดูลส่วนตัว" ทำให้การห่อหุ้มสมบูรณ์ในบางกรณี

จากนั้นมีปัญหาบางอย่างที่ทำให้ฟังก์ชั่น TH นั้นสนุกน้อยลงที่จะใช้ในฐานะนักพัฒนาห้องสมุด:

  • รหัส TH ไม่สามารถคอมโพสิตได้เสมอ สมมติว่ามีคนสร้างเครื่องกำเนิดไฟฟ้าสำหรับเลนส์และบ่อยกว่านั้นเครื่องกำเนิดนั้นจะถูกจัดโครงสร้างในลักษณะที่สามารถเรียกได้โดยตรงจาก "ผู้ใช้ปลายทาง" และไม่ใช่รหัส TH อื่น ๆ ตัวอย่างเช่นการถ่าย รายการตัวสร้างประเภทเพื่อสร้างเลนส์เพื่อเป็นพารามิเตอร์ generateLenses [''Foo, ''Bar]มันเป็นเรื่องยุ่งยากที่จะสร้างรายการในรหัสว่าในขณะที่ผู้ใช้เท่านั้นที่มีการเขียน
  • นักพัฒนายังไม่ทราบว่าสามารถสร้างรหัส TH ได้ คุณรู้ไหมว่าคุณสามารถเขียนforM_ [''Foo, ''Bar] generateLens? Qเป็นเพียง monad ดังนั้นคุณสามารถใช้ฟังก์ชั่นปกติทั้งหมดกับมันได้ บางคนไม่ทราบเรื่องนี้และด้วยเหตุนี้พวกเขาจึงสร้างฟังก์ชั่นเดียวกันหลายฟังก์ชั่นที่มีการใช้งานมากเกินไปและฟังก์ชั่นเหล่านี้ทำให้เกิดการขยายตัวที่แน่นอน นอกจากนี้คนส่วนใหญ่เขียนกำเนิดของพวกเขาในQmonad แม้ว่าพวกเขาจะได้ไม่ต้องซึ่งเป็นเหมือนการเขียนbla :: IO Int; bla = return 3; คุณให้ฟังก์ชั่น "สิ่งแวดล้อม" มากกว่าที่มันต้องการและลูกค้าของฟังก์ชั่นจะต้องให้สภาพแวดล้อมนั้นเป็นผลของมัน

ท้ายที่สุดมีบางสิ่งที่ทำให้ฟังก์ชั่น TH นั้นสนุกน้อยลงที่จะใช้ในฐานะผู้ใช้ปลายทาง:

  • ความทึบแสง เมื่อฟังก์ชั่น TH มีประเภทQ Decมันสามารถสร้างทุกอย่างที่ระดับบนสุดของโมดูลและคุณไม่สามารถควบคุมสิ่งที่จะสร้างขึ้นได้
  • Monolithism คุณไม่สามารถควบคุมฟังก์ชัน TH ที่สร้างขึ้นได้เว้นแต่ว่าผู้พัฒนาอนุญาต หากคุณพบฟังก์ชั่นที่สร้างอินเตอร์เฟสฐานข้อมูลและอินเตอร์เฟสการทำให้เป็นอันดับของ JSON คุณไม่สามารถพูดว่า "ไม่ฉันต้องการเพียงแค่ส่วนต่อประสานฐานข้อมูลขอขอบคุณ; ฉันจะหมุนส่วนติดต่อ JSON ของฉันเอง"
  • ใช้เวลา รหัส TH ใช้เวลาค่อนข้างนานในการรัน รหัสจะถูกตีความใหม่อีกครั้งทุกครั้งที่มีการรวบรวมไฟล์และบ่อยครั้งที่แพ็คเกจ TH จำเป็นต้องใช้โค้ดจำนวนมากซึ่งจะต้องโหลด ทำให้เวลาในการรวบรวมช้าลงอย่างเห็นได้ชัด

4
เพิ่มความจริงที่ว่าเทมเพลต -Kell ได้รับเอกสารที่ไม่ดีในอดีต (แม้ว่าฉันเพิ่งจะดูอีกครั้งและดูเหมือนว่าตอนนี้สิ่งต่าง ๆ จะดีขึ้นเล็กน้อยอย่างน้อย) นอกจากนี้เพื่อให้เข้าใจแม่แบบ Haskell คุณต้องเข้าใจไวยากรณ์ภาษา Haskell เป็นหลักซึ่งมีความซับซ้อนจำนวนหนึ่ง (ไม่มีแบบแผน) สองสิ่งนี้มีส่วนทำให้ฉันตั้งใจไม่รบกวนที่จะเข้าใจ TH เมื่อฉันเป็นผู้เริ่มต้น Haskell
mightybyte

14
อย่าลืมว่าการใช้เทมเพลตแฮสเค็ลล์นั้นหมายถึงลำดับการประกาศ! TH ไม่ได้รวมเข้าด้วยกันอย่างแน่นหนาอย่างที่ใคร ๆ คาดหวังจากการขัดเงาของ Haskell (ไม่ว่าจะเป็น 1.4, '98, 2010 หรือแม้แต่กลาสโกว์)
Thomas M. DuBuisson

13
คุณสามารถให้เหตุผลเกี่ยวกับ Haskell ได้โดยไม่ยากเกินไปไม่มีการรับประกันเกี่ยวกับ Template Haskell
augustss

15
และเกิดอะไรขึ้นกับคำมั่นสัญญาของโอเล็กเรื่องทางเลือกที่ปลอดภัยสำหรับ TH? ผมหมายถึงการทำงานของเขาตามออกของเขา "ในที่สุด Tagless ประเมินบางส่วน" กระดาษและอื่น ๆ ของบันทึกของเขาที่นี่ มันดูดีมากเมื่อพวกเขาประกาศมันแล้วฉันก็ไม่เคยได้ยินคำพูดเกี่ยวกับมันอีกเลย
Gabriel Gonzalez


53

นี่เป็นเพียงความเห็นของฉันเท่านั้น

  • มันน่าเกลียดที่จะใช้ $(fooBar ''Asdf)เพียงแค่ดูไม่ดี ผิวเผินแน่นอน แต่มันมีส่วนช่วย

  • แม้แต่ผู้เขียนที่น่าเกลียดก็ยังเขียน บางครั้งการอ้างถึงใช้งานได้ แต่หลายครั้งที่คุณต้องทำ AST การรับสินบนและการประปาด้วยตนเอง APIที่มีขนาดใหญ่และเทอะทะมีเสมอมากในกรณีที่คุณไม่สนใจเกี่ยวกับ แต่ยังคงต้องจัดส่งและกรณีที่คุณจะดูแลเกี่ยวกับการมีแนวโน้มที่จะอยู่ในหลายรูปแบบที่คล้ายกัน แต่ไม่เหมือนกัน (เทียบกับข้อมูล Newtype บันทึก - style เทียบกับ constructors ปกติและอื่น ๆ ) มันน่าเบื่อและซ้ำซากในการเขียนและซับซ้อนพอที่จะไม่ใช้กลไก ปฏิรูปข้อเสนอที่อยู่บางนี้ (ทำให้คำพูดมากขึ้นอย่างกว้างขวางบังคับ)

  • การ จำกัด เวทีคือนรก การไม่สามารถประกบฟังก์ชั่นที่กำหนดไว้ในโมดูลเดียวกันนั้นเป็นส่วนเล็ก ๆ ของมัน: ผลที่ตามมาคือถ้าคุณมีการต่อรอยระดับบนสุดทุกอย่างหลังจากมันในโมดูลจะอยู่นอกขอบเขตของสิ่งใด ๆ ก่อนหน้านี้ ภาษาอื่นที่มีคุณสมบัตินี้ (C, C ++) ทำให้มันใช้งานได้โดยอนุญาตให้คุณส่งต่อสิ่งที่ประกาศ แต่ Haskell ไม่ได้ หากคุณต้องการการอ้างอิงแบบวนซ้ำระหว่างการประกาศแบบต่อเชื่อมหรือการอ้างอิงและการพึ่งพาของพวกเขาคุณมักจะเมา

  • มันไม่มีระเบียบวินัย สิ่งที่ฉันหมายถึงคือเวลาส่วนใหญ่เมื่อคุณแสดงสิ่งที่เป็นนามธรรมมีหลักการหรือแนวคิดบางอย่างที่อยู่เบื้องหลังสิ่งที่เป็นนามธรรม สำหรับหลาย abstractions หลักการเบื้องหลังพวกเขาสามารถแสดงในประเภทของพวกเขา สำหรับคลาสชนิดคุณสามารถกำหนดกฎหมายซึ่งอินสแตนซ์ควรเชื่อฟังและไคลเอนต์สามารถสันนิษฐานได้ หากคุณใช้คุณสมบัติทั่วไปของ GHC เพื่อสรุปรูปแบบของการประกาศอินสแตนซ์ของประเภทข้อมูลใด ๆ (ภายในขอบเขต) คุณจะต้องพูดว่า "สำหรับประเภทผลรวมมันใช้งานได้เช่นนี้สำหรับประเภทผลิตภัณฑ์มันใช้งานได้" ในทางกลับกันเทมเพลต Haskell นั้นเป็นเพียงมาโคร ไม่ใช่สิ่งที่เป็นนามธรรมในระดับความคิด แต่สิ่งที่เป็นนามธรรมในระดับของ AST ซึ่งดีกว่า แต่มีเพียงพอประมาณเท่านั้นกว่าสิ่งที่เป็นนามธรรมในระดับของข้อความล้วน *

  • มันเชื่อมโยงคุณกับ GHC ในทางทฤษฎีผู้รวบรวมรายอื่นสามารถใช้งานได้ แต่ในทางปฏิบัติฉันสงสัยว่าสิ่งนี้จะเกิดขึ้นได้ (นี่เป็นสิ่งที่ตรงกันข้ามกับส่วนขยายระบบประเภทต่าง ๆ ซึ่งแม้ว่า GHC จะสามารถนำไปใช้งานได้ในขณะนี้ แต่ฉันสามารถจินตนาการได้ว่าจะมีการนำคอมไพเลอร์อื่นมาใช้บนถนนและเป็นมาตรฐานในที่สุด)

  • API ไม่เสถียร เมื่อเพิ่มฟีเจอร์ภาษาใหม่ลงใน GHC และแพคเกจ template-haskell ได้รับการอัปเดตเพื่อรองรับคุณสมบัติเหล่านี้มักจะเกี่ยวข้องกับการเปลี่ยนแปลงที่ไม่เข้ากันกับส่วนหลังของประเภทข้อมูล TH หากคุณต้องการให้รหัส TH ของคุณสามารถทำงานร่วมกับ GHC ได้มากกว่าหนึ่งรุ่นคุณจะต้องระมัดระวังและใช้งานCPPได้

  • มีหลักการทั่วไปที่คุณควรใช้เครื่องมือที่เหมาะสมสำหรับงานและเป็นหนึ่งในที่เล็กที่สุดที่จะพอเพียงเป็นและในการเปรียบเทียบว่าแม่แบบ Haskell คืออะไรเช่นนี้ หากมีวิธีการใช้ที่ไม่ใช่เทมเพลตแฮสเค็ลล์โดยทั่วไปแล้ว

ข้อดีของเทมเพลตแฮสเค็ลล์คือคุณสามารถทำสิ่งต่าง ๆ ได้โดยที่คุณไม่สามารถทำอย่างอื่นได้และมันก็ใหญ่มาก ส่วนใหญ่แล้วสิ่งที่ TH ใช้เพื่อทำอย่างอื่นก็ต่อเมื่อมีการนำไปใช้โดยตรงเป็นคุณสมบัติของคอมไพเลอร์ TH มีประโยชน์อย่างมากที่จะมีทั้งคู่เพราะมันช่วยให้คุณทำสิ่งเหล่านี้และเพราะมันช่วยให้คุณสามารถขยายต้นแบบคอมไพเลอร์ที่มีศักยภาพในวิธีที่มีน้ำหนักเบาและนำกลับมาใช้ใหม่ได้มากขึ้น

เพื่อสรุปว่าทำไมฉันจึงคิดว่ามีความรู้สึกด้านลบต่อเทมเพลตแฮสเคลล์: มันแก้ปัญหาได้มากมาย แต่สำหรับปัญหาใดก็ตามที่แก้ได้มันรู้สึกว่าควรมีวิธีแก้ปัญหาที่ดีและสง่างามและดีกว่า หนึ่งที่ไม่แก้ปัญหาโดยการสร้างสำเร็จรูปสำเร็จรูป แต่โดยไม่จำเป็นต้องมีสำเร็จรูป

แม้ว่าฉันมักจะรู้สึกว่าCPPมีอัตราส่วนพลังงานต่อน้ำหนักที่ดีขึ้นสำหรับปัญหาเหล่านั้นที่สามารถแก้ไขได้

แก้ไข 23-04-14: สิ่งที่ฉันมักจะพยายามที่จะได้รับในข้างต้นและเพิ่งได้รับเมื่อไม่นานมานี้คือว่ามีความแตกต่างที่สำคัญระหว่างนามธรรมและการคัดลอกซ้ำ การทำนามธรรมอย่างถูกต้องมักจะส่งผลให้เกิดการซ้ำซ้อนเป็นผลข้างเคียงและการทำสำเนามักเป็นสัญญาณที่บอกเล่าของสิ่งที่เป็นนามธรรมที่ไม่เพียงพอ แต่นั่นไม่ใช่เหตุผลที่มีค่า นามธรรมที่เหมาะสมคือสิ่งที่ทำให้รหัสถูกต้องเข้าใจได้และบำรุงรักษาได้ การคัดลอกทำให้สั้นลงเท่านั้น เทมเพลต Haskell เช่นเดียวกับมาโครทั่วไปเป็นเครื่องมือสำหรับการคัดลอกข้อมูลซ้ำซ้อน


"CPP มีอัตราส่วนกำลังต่อน้ำหนักที่ดีขึ้นสำหรับปัญหาเหล่านั้นที่สามารถแก้ไขได้" จริง และใน C99 มันสามารถแก้ไขสิ่งที่คุณต้องการ พิจารณาเหล่านี้: COS , ความโกลาหล ฉันไม่ได้พูดถึงเหตุผลที่ผู้คนคิดว่าการสร้าง AST ดีกว่า มันเป็นความคลุมเครือมากขึ้นและตั้งฉากกับภาษาอื่นน้อยลง
บริททันเคริน

31

ฉันต้องการพูดถึงบางประเด็นที่ dflemstr แสดงขึ้น

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

หากนิพจน์ TH / quasi-quoter ทำสิ่งที่ล้ำสมัยจนมุมที่มีเล่ห์เหลี่ยมสามารถซ่อนได้

ฉันทำลายกฎนี้ไม่น้อยกับกึ่ง quoters ฉันได้รับการทำงานในเร็ว ๆ นี้ (ใช้ Haskell-src-กักพวกต่างดาว / เมตา) - https://github.com/mgsloan/quasi-extras/tree/master/examples ฉันรู้ว่าสิ่งนี้นำเสนอข้อบกพร่องบางอย่างเช่นไม่สามารถประกบกันในรายการความเข้าใจทั่วไป อย่างไรก็ตามฉันคิดว่ามีโอกาสที่ดีที่ความคิดบางอย่างในhttp://hackage.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposalจะสิ้นสุดในคอมไพเลอร์ จนกว่าจะถึงตอนนั้นห้องสมุดสำหรับการแยกวิเคราะห์ Haskell ไปยังต้นไม้ TH นั้นเป็นการประมาณที่สมบูรณ์แบบ

เกี่ยวกับการรวบรวมความเร็ว / การอ้างอิงเราสามารถใช้แพคเกจ "zeroth" เพื่ออินไลน์โค้ดที่สร้างขึ้น อย่างน้อยก็เป็นสิ่งที่ดีสำหรับผู้ใช้ของห้องสมุดที่กำหนด แต่เราไม่สามารถทำได้ดีกว่านี้สำหรับกรณีของการแก้ไขห้องสมุด TH การพึ่งพากันแบบขยาย bloat สามารถสร้างไบนารีได้หรือไม่? ฉันคิดว่ามันเหลือทุกอย่างที่ไม่ได้อ้างอิงโดยโค้ดที่คอมไพล์แล้ว

การ จำกัด การแยกสถานะ / การแยกของขั้นตอนการคอมไพล์ของโมดูล Haskell จะถูกดูด

ความทึบของ RE: มันเหมือนกับฟังก์ชั่นไลบรารีใด ๆ ที่คุณเรียก คุณไม่มีสิทธิ์ควบคุม Data.List.groupBy ว่าจะทำอะไร คุณเพียงแค่มี "การรับประกัน" / การประชุมที่สมเหตุสมผลว่าหมายเลขรุ่นบอกบางอย่างเกี่ยวกับความเข้ากันได้ มันเป็นเรื่องของการเปลี่ยนแปลงที่แตกต่างกันเมื่อ

นี่คือที่ที่ใช้ zeroth จ่ายเงิน - คุณได้กำหนดเวอร์ชันของไฟล์ที่สร้างไว้แล้วดังนั้นคุณจะรู้ได้เสมอว่าเมื่อใดที่รูปแบบของรหัสที่สร้างมีการเปลี่ยนแปลง การมองที่ diffs อาจจะดูไม่ค่อยดีนักสำหรับโค้ดที่สร้างขึ้นจำนวนมากดังนั้นนี่คือที่เดียวที่อินเทอร์เฟซผู้พัฒนาที่ดีกว่าจะมีประโยชน์

RE Monolithism: คุณสามารถโพสต์ผลการแสดงออก TH โดยใช้รหัสเวลาคอมไพล์ของคุณเอง มันจะไม่เป็นรหัสที่จะกรองตามประเภท / ชื่อประกาศระดับบนสุด Heck คุณสามารถจินตนาการการเขียนฟังก์ชั่นที่ทำสิ่งนี้โดยทั่วไป สำหรับการปรับเปลี่ยน / ยกเลิกการปรับเปลี่ยน quasiquoters คุณสามารถจัดรูปแบบการจับคู่กับ "QuasiQuoter" และแยกการแปลงที่ใช้หรือสร้างใหม่ในแง่ของเก่า


1
เกี่ยวกับOpacity / Monolithism:แน่นอนว่าคุณสามารถดำเนินการ a [Dec]และลบสิ่งที่คุณไม่ต้องการได้ แต่สมมติว่าฟังก์ชั่นอ่านไฟล์คำจำกัดความภายนอกเมื่อสร้างอินเตอร์เฟส JSON เพียงเพราะคุณไม่ได้ใช้ซึ่งDecไม่ได้ทำให้ตัวสร้างหยุดค้นหาไฟล์คำจำกัดความทำให้การรวบรวมล้มเหลว ด้วยเหตุนี้จึงเป็นการดีที่จะมีรุ่นที่ จำกัด ของQmonad ที่อนุญาตให้คุณสร้างชื่อใหม่ (และสิ่งต่าง ๆ ) แต่ไม่อนุญาตIOดังนั้นอย่างที่คุณบอกว่าหนึ่งสามารถกรองผลลัพธ์ / ทำองค์ประกอบอื่น ๆ .
dflemstr

1
ฉันเห็นด้วยควรมีคิว / ใบเสนอราคาที่ไม่ใช่ IO! นอกจากนี้ยังจะช่วยให้การแก้ปัญหา - stackoverflow.com/questions/7107308/... เมื่อคุณตรวจสอบให้แน่ใจว่ารหัสเวลาคอมไพล์ไม่ได้ทำอะไรที่ไม่ปลอดภัยดูเหมือนว่าคุณจะสามารถเรียกใช้ตัวตรวจสอบความปลอดภัยของรหัสผลลัพธ์และตรวจสอบให้แน่ใจว่ามันไม่ได้อ้างอิงสิ่งส่วนตัว
mgsloan

1
คุณเคยเขียนถึงการโต้แย้งโต้แย้งของคุณหรือไม่? ยังคงรอลิงก์ที่คุณสัญญาไว้ สำหรับผู้ที่กำลังมองหาเนื้อหาเก่าของคำตอบนี้: stackoverflow.com/revisions/10859441/1และสำหรับผู้ที่สามารถดูเนื้อหาที่ถูกลบ: stackoverflow.com/revisions/10913718/6
Dan Burton

1
มีเวอร์ชันล่าสุดของ zeroth มากกว่าแฮ็คแฮ็คหรือไม่ หนึ่ง (และ darcs repo) อัปเดตล่าสุดในปี 2009 สำเนาทั้งสองไม่ได้สร้างด้วย ghc ปัจจุบัน (7.6)
aavogt

1
@aavogt tgeeky กำลังแก้ไขปัญหาอยู่ แต่ฉันไม่คิดว่าเขาจะทำเสร็จ: github.com/technogeeky/zeroth ถ้าไม่มีใครทำ / ทำสิ่งนี้ฉันจะไปหามันในที่สุด
mgsloan

16

คำตอบนี้เป็นการตอบสนองต่อปัญหาที่นำโดย illissius จุดต่อจุด:

  • มันน่าเกลียดที่จะใช้ $ (fooBar '' Asdf) แค่ดูไม่ดี ผิวเผินแน่นอน แต่มันมีส่วนช่วย

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

  • แม้แต่ผู้เขียนที่น่าเกลียดก็ยังเขียน บางครั้งการอ้างถึงใช้งานได้ แต่หลายครั้งที่คุณต้องทำ AST การรับสินบนและการประปาด้วยตนเอง [API] [1] มีขนาดใหญ่และเทอะทะมีหลายกรณีที่คุณไม่สนใจ แต่ยังคงต้องส่งและกรณีที่คุณสนใจมักจะปรากฏในรูปแบบที่คล้ายกัน แต่ไม่เหมือนกันหลายรูปแบบ (ข้อมูล เทียบกับ newtype, style-record เทียบกับ constructor ปกติและอื่น ๆ ) มันน่าเบื่อและซ้ำซากในการเขียนและซับซ้อนพอที่จะไม่ใช้กลไก [ข้อเสนอการปฏิรูป] [2] กล่าวถึงเรื่องนี้บางส่วน

ฉันยังเห็นด้วยกับเรื่องนี้อย่างไรก็ตามในขณะที่ความคิดเห็นบางส่วนใน "ทิศทางใหม่สำหรับ TH" สังเกตว่าการขาดการอ้างอิง AST ที่ดีนอกกรอบไม่ใช่ข้อบกพร่องที่สำคัญ ในแพคเกจ WIP นี้ผมพยายามที่จะแก้ไขปัญหาเหล่านี้ในรูปแบบห้องสมุด: https://github.com/mgsloan/quasi-extras จนถึงตอนนี้ฉันอนุญาตให้ประกบกันในสถานที่ไม่กี่แห่งมากกว่าปกติและสามารถจับคู่รูปแบบกับ AST ได้

  • การ จำกัด เวทีคือนรก การไม่สามารถประกบฟังก์ชั่นที่กำหนดไว้ในโมดูลเดียวกันนั้นเป็นส่วนเล็ก ๆ ของมัน: ผลที่ตามมาคือถ้าคุณมีการต่อรอยระดับบนสุดทุกอย่างหลังจากมันในโมดูลจะอยู่นอกขอบเขตของสิ่งใด ๆ ก่อนหน้านี้ ภาษาอื่นที่มีคุณสมบัตินี้ (C, C ++) ทำให้มันใช้งานได้โดยอนุญาตให้คุณส่งต่อสิ่งที่ประกาศ แต่ Haskell ไม่ได้ หากคุณต้องการการอ้างอิงแบบวนซ้ำระหว่างการประกาศแบบต่อเชื่อมหรือการอ้างอิงและการพึ่งพาของพวกเขาคุณมักจะเมา

ฉันเคยพบปัญหานิยามคำนิยาม TH ที่เป็นไปไม่ได้มาก่อน ... มันค่อนข้างน่ารำคาญ มีวิธีแก้ปัญหา แต่มันน่าเกลียด - ห่อสิ่งที่เกี่ยวข้องในการพึ่งพาวงจรในการแสดงออก TH ที่รวมการประกาศทั้งหมดที่สร้างขึ้น หนึ่งในเครื่องกำเนิดไฟฟ้าที่ประกาศเหล่านี้อาจเป็นเสมือน quer-quoter ที่ยอมรับรหัส Haskell

  • มันไม่มีหลักการ สิ่งที่ฉันหมายถึงคือเวลาส่วนใหญ่เมื่อคุณแสดงสิ่งที่เป็นนามธรรมมีหลักการหรือแนวคิดบางอย่างที่อยู่เบื้องหลังสิ่งที่เป็นนามธรรม สำหรับหลาย abstractions หลักการเบื้องหลังพวกเขาสามารถแสดงในประเภทของพวกเขา เมื่อคุณกำหนดคลาสประเภทคุณมักจะสามารถกำหนดกฎหมายซึ่งอินสแตนซ์ที่ควรเชื่อฟังและลูกค้าสามารถสมมติได้ หากคุณใช้ [คุณสมบัติทั่วไปใหม่ของ GHC] [3] เพื่อสรุปรูปแบบของการประกาศอินสแตนซ์ในประเภทข้อมูลใด ๆ (ภายในขอบเขต) คุณจะต้องพูดว่า "สำหรับประเภทผลรวมมันใช้งานได้เช่นนี้สำหรับประเภทผลิตภัณฑ์มันทำงานเช่นนั้น " แต่เทมเพลตแฮสเคลล์เป็นเพียงมาโครที่โง่ ไม่ใช่สิ่งที่เป็นนามธรรมในระดับความคิด แต่สิ่งที่เป็นนามธรรมในระดับของ AST ซึ่งดีกว่า แต่มีเพียงพอประมาณเท่านั้นกว่าสิ่งที่เป็นนามธรรมในระดับของข้อความล้วน

มันไร้ศีลธรรมก็ต่อเมื่อคุณทำสิ่งที่ไร้ศีลธรรมกับมัน ข้อแตกต่างเพียงอย่างเดียวคือเมื่อคอมไพเลอร์ใช้กลไกสำหรับนามธรรมคุณมีความมั่นใจมากขึ้นว่านามธรรมไม่รั่วไหล บางทีการออกแบบภาษาที่เป็นประชาธิปไตยอาจฟังดูน่ากลัว! ผู้สร้างห้องสมุด TH ต้องจัดทำเอกสารอย่างดีและชัดเจนกำหนดความหมายและผลลัพธ์ของเครื่องมือที่พวกเขามีให้ ตัวอย่างที่ดีของหลักการ TH คือแพ็กเกจที่ได้รับ: http://hackage.haskell.org/package/derive - มันใช้ DSL เพื่อเป็นตัวอย่างของการพิสูจน์ / ระบุ / การสืบทอดที่แท้จริง

  • มันเชื่อมโยงคุณกับ GHC ในทางทฤษฎีผู้รวบรวมรายอื่นสามารถใช้งานได้ แต่ในทางปฏิบัติฉันสงสัยว่าสิ่งนี้จะเกิดขึ้นได้ (นี่เป็นสิ่งที่ตรงกันข้ามกับส่วนขยายระบบประเภทต่าง ๆ ซึ่งแม้ว่า GHC จะสามารถนำไปใช้งานได้ในขณะนี้ แต่ฉันสามารถจินตนาการได้ว่าจะมีการนำคอมไพเลอร์อื่นมาใช้บนถนนและเป็นมาตรฐานในที่สุด)

นั่นเป็นจุดที่ดีทีเดียว - TH API นั้นค่อนข้างใหญ่และน่าเบื่อ การใช้งานซ้ำอีกครั้งดูเหมือนว่าอาจจะยาก อย่างไรก็ตามมีเพียงไม่กี่วิธีเท่านั้นในการแบ่งปัญหาของการเป็นตัวแทนของ Haskell AST ฉันจินตนาการว่าการคัดลอก TH ADT และการเขียนตัวแปลงไปยังการเป็นตัวแทน AST ภายในจะทำให้คุณได้รับประโยชน์อย่างมาก นี่จะเทียบเท่ากับความพยายาม (ไม่สำคัญ) ในการสร้าง Haskell-src-meta นอกจากนี้ยังสามารถนำมาใช้ใหม่ได้ง่ายๆโดยการพิมพ์ TH AST และการใช้เครื่องมือแยกวิเคราะห์ภายในของคอมไพเลอร์

ในขณะที่ฉันอาจจะผิดฉันไม่เห็นว่า TH เป็นส่วนขยายที่ซับซ้อนของคอมไพเลอร์จากมุมมองการใช้งาน นี่คือหนึ่งในประโยชน์ของการ "ทำให้มันง่าย" และไม่มีชั้นพื้นฐานที่น่าดึงดูดในเชิงทฤษฎี

  • API ไม่เสถียร เมื่อเพิ่มฟีเจอร์ภาษาใหม่ลงใน GHC และแพคเกจ template-haskell ได้รับการอัปเดตเพื่อรองรับคุณสมบัติเหล่านี้มักจะเกี่ยวข้องกับการเปลี่ยนแปลงที่ไม่เข้ากันกับส่วนหลังของประเภทข้อมูล TH หากคุณต้องการให้รหัส TH ของคุณสามารถทำงานร่วมกับ GHC ได้มากกว่าหนึ่งรุ่นคุณจะต้องระมัดระวังและใช้งานCPPได้

นี่เป็นจุดที่ดี แต่ค่อนข้างน่าสนใจ ในขณะที่มีการเพิ่ม API เมื่อเร็ว ๆ นี้พวกเขายังไม่ได้รับความเสียหายอย่างกว้างขวาง นอกจากนี้ฉันคิดว่าด้วยการอ้างอิง AST ที่เหนือกว่าที่ฉันกล่าวถึงก่อนหน้านี้ API ที่จำเป็นต้องใช้จริงนั้นสามารถลดลงได้อย่างมาก หากไม่มีสิ่งก่อสร้าง / การจับคู่ที่ต้องการฟังก์ชั่นที่แตกต่างกันและจะแสดงเป็นตัวอักษรแทน API ส่วนใหญ่จะหายไป ยิ่งไปกว่านั้นรหัสที่คุณเขียนจะทำให้พอร์ตง่ายขึ้นสำหรับการเป็นตัวแทน AST สำหรับภาษาที่คล้ายกับ Haskell


โดยสรุปแล้วฉันคิดว่า TH เป็นเครื่องมือที่ทรงพลังและไม่ได้รับความสนใจ ความเกลียดชังที่น้อยลงอาจนำไปสู่ระบบนิเวศที่มีชีวิตชีวามากขึ้นของห้องสมุดสนับสนุนการใช้ต้นแบบคุณลักษณะภาษาเพิ่มเติม มีการตั้งข้อสังเกตว่า TH เป็นเครื่องมือที่มีอำนาจเหนือกว่าที่สามารถให้คุณ / ทำ / เกือบทุกอย่าง โกลาหล! ฉันคิดว่าพลังนี้ช่วยให้คุณสามารถเอาชนะข้อ จำกัด ส่วนใหญ่และสร้างระบบที่สามารถใช้วิธีการเขียนโปรแกรมเมตาค่อนข้างดี มันคุ้มค่ากับการใช้แฮ็กที่น่าเกลียดเพื่อจำลองการใช้งาน "เหมาะสม" เนื่องจากวิธีนี้การออกแบบการใช้งาน "เหมาะสม" จะค่อยๆชัดเจนขึ้น

ในนิพพานในอุดมคติส่วนตัวของฉันภาษาส่วนใหญ่จะย้ายออกจากคอมไพเลอร์ไปสู่ห้องสมุดของความหลากหลายเหล่านี้ ความจริงที่ว่าคุณลักษณะถูกนำมาใช้เนื่องจากห้องสมุดไม่ได้มีอิทธิพลอย่างมากต่อความสามารถในการสรุปอย่างซื่อสัตย์

Haskell คือคำตอบทั่วไปสำหรับรหัส boilerplate? สิ่งที่เป็นนามธรรม สิ่งที่เราชื่นชอบคืออะไร? ฟังก์ชั่นและพิมพ์ดีด!

Typeclasses ให้เรากำหนดชุดของเมธอดที่สามารถใช้ในฟังก์ชันทั่วไปในคลาสนั้น อย่างไรก็ตามนอกเหนือจากนี้วิธีเดียวที่จะช่วยให้คลาสหลีกเลี่ยงการสร้างแผ่นข้อมูลด้วยการเสนอ "คำจำกัดความเริ่มต้น" ตอนนี้นี่เป็นตัวอย่างของคุณสมบัติที่ไม่มีหลักการ!

  • ชุดการรวมที่น้อยที่สุดไม่สามารถประกาศได้ / คอมไพเลอร์สามารถตรวจสอบได้ สิ่งนี้อาจนำไปสู่คำจำกัดความที่ไม่ตั้งใจซึ่งให้ผลด้านล่างเนื่องจากการเรียกซ้ำซึ่งกันและกัน

  • แม้จะมีความสะดวกสบายมากและอำนาจนี้จะให้ผลผลิตคุณไม่สามารถระบุค่าเริ่มต้น superclass เนื่องจากกรณีเด็กกำพร้า http://lukepalmer.wordpress.com/2009/01/25/a-world-without-orphans/ เหล่านี้จะช่วยให้เราแก้ไข ลำดับชั้นตัวเลขอย่างงดงาม!

  • ไปหลังจาก TH-เช่นความสามารถในการเป็นค่าเริ่มต้นนำไปสู่วิธีการhttp://www.haskell.org/haskellwiki/GHC.Generics ในขณะที่นี่คือสิ่งที่ดีประสบการณ์เดียวของฉันการแก้จุดบกพร่องรหัสโดยใช้ข้อมูลทั่วไปเหล่านี้เป็นไปไม่ได้เนื่องจากขนาดของประเภทที่ชักนำและ ADT มีความซับซ้อนเช่นเดียวกับ AST https://github.com/mgsloan/th-extra/commit/d7784d95d396eb3abdb409a24360beb03731c88c

    กล่าวอีกนัยหนึ่งสิ่งนี้เกิดขึ้นหลังจากคุณสมบัติที่ให้บริการโดย TH แต่ต้องยกทั้งโดเมนของภาษาภาษาที่ใช้ในการสร้างลงในการแสดงระบบชนิด ในขณะที่ฉันเห็นว่ามันทำงานได้ดีสำหรับปัญหาทั่วไปของคุณสำหรับคนที่ซับซ้อน แต่ดูเหมือนว่าจะมีสัญลักษณ์กองที่น่ากลัวยิ่งกว่าแฮกเกอร์ TH

    TH ให้การคำนวณเวลาส่งออกมูลค่าระดับของรหัสผลลัพธ์ในขณะที่ generics บังคับให้คุณยกส่วนการจับคู่รูปแบบ / การเรียกซ้ำของรหัสลงในระบบประเภท แม้ว่าสิ่งนี้จะ จำกัด ผู้ใช้ด้วยวิธีที่ค่อนข้างมีประโยชน์ แต่ฉันไม่คิดว่าความซับซ้อนนั้นคุ้มค่า

ฉันคิดว่าการปฏิเสธของ TH และ metaprogramming ที่เหมือนเสียงกระเพื่อมนำไปสู่การตั้งค่าต่อสิ่งต่าง ๆ เช่นค่าเริ่มต้นของวิธีการแทนการยืดหยุ่นมากขึ้นการขยายตัวของแมโครเหมือนกับการประกาศของอินสแตนซ์ วินัยในการหลีกเลี่ยงสิ่งต่าง ๆ ที่อาจนำไปสู่ผลลัพธ์ที่ไม่ดีนั้นเป็นสิ่งที่ฉลาดอย่างไรก็ตามเราไม่ควรมองข้ามว่าระบบประเภทที่มีความสามารถของ Haskell ช่วยให้การเปรียบเทียบโปรแกรมน่าเชื่อถือมากกว่าในสภาพแวดล้อมอื่น ๆ (โดยตรวจสอบรหัสที่สร้างขึ้น)


4
คำตอบนี้ไม่สามารถยืนได้ด้วยตัวคุณเอง: คุณกำลังอ้างอิงถึงคำตอบอีกข้อหนึ่งที่ฉันต้องไปหาก่อนที่ฉันจะสามารถอ่านคำตอบของคุณได้อย่างถูกต้อง
Ben Millwood

มันเป็นความจริง. ฉันพยายามทำให้ชัดเจนว่าพูดถึงอะไร บางทีฉันอาจแก้ไขจุดอินไลน์ของ illisuis
mgsloan

ฉันควรจะบอกว่าบางที "ไร้ศีลธรรม" เป็นคำที่แข็งแกร่งกว่าที่ฉันควรจะใช้ด้วยความหมายบางอย่างที่ฉันไม่ได้ตั้งใจ - มันไม่ไร้ยางอายแน่นอน! สัญลักษณ์แสดงหัวข้อนั้นเป็นสิ่งที่ฉันมีปัญหามากที่สุดเพราะฉันมีความรู้สึกนี้หรือความคิดที่ไม่มีรูปแบบในหัวของฉันและมีปัญหาในการใส่คำพูดและ "ไม่มีศีลธรรม" เป็นหนึ่งในคำที่ฉันเข้าใจซึ่งอยู่ที่ไหนสักแห่งในบริเวณใกล้เคียง "มีวินัย" น่าจะใกล้เคียงกว่านี้ ไม่มีการกำหนดชัดเจนและชัดเจนฉันไปเพื่อตัวอย่างบางอย่างแทน หากใครบางคนสามารถอธิบายให้ฉันชัดเจนยิ่งกว่าสิ่งที่ฉันอาจหมายถึงฉันจะขอบคุณมัน!
glaebhoerl

(นอกจากนี้ผมคิดว่าคุณอาจมีการเปลี่ยนขึ้นข้อ จำกัด การแสดงละครและคำพูดการเขียนที่น่าเกลียด.)
glaebhoerl

1
Doh! ขอบคุณสำหรับการชี้ให้เห็น! แก้ไขแล้ว. ใช่ไม่มีระเบียบวินัยอาจเป็นวิธีที่ดีกว่าของการวางไว้ ฉันคิดว่าความแตกต่างที่นี่เป็นจริงระหว่าง "ในตัว" ดังนั้น "กลไกที่เป็นนามธรรม" ที่เป็นที่รู้จักดีเมื่อเทียบกับ "ad-hoc" หรือกลไกที่เป็นนามธรรมที่ผู้ใช้กำหนด ฉันคิดว่าสิ่งที่ฉันหมายถึงคือคุณสามารถกำหนดห้องสมุด TH ซึ่งดำเนินการบางอย่างที่คล้ายกับการพิมพ์ดีดแบบคลาสสิก (แม้ว่าในเวลาคอมไพล์ไม่ใช่เวลารันไทม์)
mgsloan

8

ปัญหาอย่างหนึ่งที่ใช้งานได้จริงกับ Template Haskell ก็คือมันใช้ได้เฉพาะเมื่อล่าม bytecode ของ GHC มีให้บริการเท่านั้นซึ่งไม่ได้เกิดขึ้นในทุกสถาปัตยกรรม ดังนั้นหากโปรแกรมของคุณใช้ Template Haskell หรืออาศัยไลบรารีที่ใช้มันจะไม่ทำงานบนเครื่องที่มี ARM, MIPS, S390 หรือ PowerPC CPU

สิ่งนี้มีความเกี่ยวข้องในทางปฏิบัติ: git-annexเป็นเครื่องมือที่เขียนใน Haskell ที่เหมาะสมสำหรับการใช้งานบนเครื่องที่ต้องกังวลเกี่ยวกับการจัดเก็บ โดยส่วนตัวแล้วฉันใช้ git-annex บนNSLU 2 (RAM 32 MB, 266MHz CPU; คุณรู้หรือไม่ว่า Haskell ทำงานได้ดีกับฮาร์ดแวร์ดังกล่าว?) ถ้าใช้กับ Template Haskell จะเป็นไปไม่ได้

(สถานการณ์เกี่ยวกับ GHC บน ARM กำลังปรับปรุงอยู่ทุกวันนี้และฉันคิดว่า 7.4.2 ใช้งานได้ดี แต่ประเด็นยังคงอยู่)


1
“ เทมเพลตแฮสเคลล์นั้นอาศัยคอมไพเลอร์ bytecode และล่ามในตัวของ GHC เพื่อใช้งานการแสดงออกต่อกัน” - haskell.org/ghc/docs/7.6.2/html/users_guide/ ......
Joachim Breitner

2
อ่าฉันว่า - ไม่ TH ไม่สามารถทำงานได้หากไม่มีล่าม bytecode แต่แตกต่างจาก (แม้ว่าจะเกี่ยวข้องกับ) ghci ฉันจะไม่แปลกใจถ้ามีความสัมพันธ์ที่สมบูรณ์แบบระหว่างความพร้อมใช้งานของ ghci และความพร้อมใช้งานของล่าม bytecode เนื่องจาก ghci ขึ้นอยู่กับล่าม bytecode แต่ปัญหาที่เกิดขึ้นคือการขาดล่าม bytecode ไม่ใช่การขาด ghci เฉพาะ
muhmuhten

1
(บังเอิญ ghci ได้รับการสนับสนุนอย่างไม่น่าเชื่อสำหรับการใช้งานแบบโต้ตอบของ TH ลองghci -XTemplateHaskell <<< '$(do Language.Haskell.TH.runIO $ (System.Random.randomIO :: IO Int) >>= print; [| 1 |] )')
muhmuhten

ตกลงด้วย ghci ฉันหมายถึงความสามารถของ GHC ในการตีความรหัส (แทนที่จะรวบรวม) เป็นอิสระจากว่ารหัสมาโต้ตอบในไบนารี ghci หรือจากประกบ TH
Joachim Breitner

6

เหตุใด TH จึงไม่ดี สำหรับฉันมันลงมาที่นี่:

หากคุณต้องการสร้างรหัสซ้ำ ๆ มากมายที่คุณคิดว่าพยายามใช้ TH เพื่อสร้างรหัสอัตโนมัติคุณกำลังทำผิด!

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

แน่นอนว่าบางครั้งก็จำเป็น แต่บางครั้งคุณสามารถหลีกเลี่ยงความต้องการ TH โดยเพียงแค่เพิ่มความฉลาดในการออกแบบของคุณ

(อีกสิ่งหนึ่งคือ TH ค่อนข้างต่ำไม่มีการออกแบบระดับสูงที่ยิ่งใหญ่รายละเอียดการใช้งานภายในของ GHC จำนวนมากถูกเปิดเผยและทำให้ API มีแนวโน้มที่จะเปลี่ยนแปลง ... )


ฉันไม่คิดว่ามันหมายความว่าภาษาหรือแอปพลิเคชันของคุณทำให้คุณล้มเหลวโดยเฉพาะถ้าเราพิจารณา QuasiQuotes มักจะมีการแลกเปลี่ยนเมื่อมันมาถึงไวยากรณ์ ไวยากรณ์บางตัวอธิบายโดเมนได้ดีกว่าดังนั้นคุณจึงต้องการสลับไปใช้ไวยากรณ์อื่นในบางครั้ง QuasiQuotes อนุญาตให้คุณสลับระหว่างไวยากรณ์อย่างหรูหรา มีประสิทธิภาพมากและ Yesod ใช้และแอพอื่น ๆ ความสามารถในการเขียนโค้ดการสร้าง HTML โดยใช้ไวยากรณ์ที่รู้สึกเหมือน HTML เป็นคุณสมบัติที่น่าทึ่ง
CoolCodeBro

@CoolCodeBro ใช่การ quasi-quoting ค่อนข้างดีและฉันคิดว่า orthogonal เล็กน้อยกับ TH (เห็นได้ชัดว่ามันถูกนำไปใช้ด้านบนของ TH.) ฉันคิดถึงการใช้ TH เพื่อสร้างอินสแตนซ์ของชั้นเรียนหรือสร้างฟังก์ชั่นของ arities หลายแบบหรืออะไรทำนองนั้น
คณิตศาสตร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.