อะไรคือความแตกต่างหลักระหว่าง Haskell และ F #? [ปิด]


135

ฉันค้นหาบนอินเทอร์เน็ตเพื่อเปรียบเทียบระหว่างF #และHaskellแต่ไม่พบอะไรที่ชัดเจน อะไรคือความแตกต่างหลักและเหตุใดฉันจึงต้องการเลือกอย่างใดอย่างหนึ่ง


1
สิ่งที่ดีเกี่ยวกับ F # คือเนื่องจากกระบวนทัศน์แบบผสมจึงเป็นจุดเริ่มต้นที่ดีกว่าสำหรับโปรแกรมเมอร์ OO เขาสามารถค่อยๆเร่งความเร็วด้วยการคิดเชิงหน้าที่และยังคงถอยกลับไปใช้ห้องสมุด OO ที่คุ้นเคยเหมือนที่เขามีใน C # Haskell บังคับให้ enchilada ใช้งานได้ทั้งหมดกับคุณในคราวเดียว
Mario

โปรดทราบว่า F # ไม่ใช่ภาษาโปรแกรมที่ใช้งานได้ อย่างไรก็ตามมันนำมาใช้ค่อนข้างน้อยจาก FP ดังนั้นจึงเป็นไปได้ที่จะพบว่าอาจมีความคล้ายคลึงกันมาก แต่อย่างไรก็ตามโดยหลักแล้วฉันจะบอกว่ามันเป็นภาษาที่แตกต่างกัน
MasterMastic

คำตอบ:


128

Haskell เป็นภาษาที่ใช้งานได้ "บริสุทธิ์" โดยที่ F # มีลักษณะของทั้งภาษาที่จำเป็น / OO และภาษาที่ใช้งานได้ Haskell ยังมีการประเมินแบบขี้เกียจซึ่งค่อนข้างหายากในภาษาที่ใช้งานได้

สิ่งเหล่านี้หมายถึงอะไร? ภาษาที่ใช้งานได้อย่างแท้จริงหมายความว่าไม่มีผลข้างเคียง (หรือการเปลี่ยนแปลงในสถานะที่ใช้ร่วมกันเมื่อมีการเรียกใช้ฟังก์ชัน) ซึ่งหมายความว่าคุณจะได้รับการรับรองว่าหากคุณเรียกใช้ f (x) จะไม่มีอะไรเกิดขึ้นนอกจากส่งคืนค่าจากฟังก์ชัน เช่นเอาต์พุตคอนโซลเอาต์พุตฐานข้อมูลการเปลี่ยนแปลงตัวแปรโกลบอลหรือแบบคงที่ .. และแม้ว่า Haskell สามารถมีฟังก์ชันที่ไม่บริสุทธิ์ (ผ่าน monads) ได้ แต่ก็ต้องมี 'โดยนัย' โดยนัยผ่านการประกาศ

ภาษาที่ใช้งานได้อย่างแท้จริงและการเขียนโปรแกรม 'ไม่มีผลข้างเคียง' ได้รับความนิยมเมื่อเร็ว ๆ นี้เนื่องจากมีการใช้งานพร้อมกันหลายคอร์ได้เป็นอย่างดีเนื่องจากการผิดพลาดโดยไม่มีสถานะที่ใช้ร่วมกันนั้นยากกว่าการล็อกและเซมาโฟร์มากมาย

การประเมินความเกียจคร้านคือการที่ฟังก์ชันไม่ได้รับการประเมินจนกว่าจะจำเป็นอย่างยิ่ง หมายความว่าสามารถหลีกเลี่ยงการดำเนินการหลายอย่างได้เมื่อไม่จำเป็น คิดสิ่งนี้ใน C # พื้นฐานถ้าประโยคเช่นนี้:

if(IsSomethingTrue() && AnotherThingTrue())
{
    do something;
}

ถ้าIsSomethingTrue()เป็นเท็จAnotherThingTrue()วิธีการจะไม่ถูกประเมิน

ในขณะที่ Haskell เป็นภาษาที่น่าทึ่ง แต่ประโยชน์หลักของ F # (ในขณะนี้) ก็คือมันอยู่ด้านบนของ CLR สิ่งนี้ยืมตัวเองไปสู่การเขียนโปรแกรมหลายภาษา วันหนึ่งคุณอาจเขียน UI ของเว็บใน ASP.net MVC ตรรกะทางธุรกิจของคุณใน C # อัลกอริทึมหลักของคุณใน F # และการทดสอบหน่วยของคุณใน Ironruby .... ทั้งหมดในกรอบ. Net

ฟังวิทยุวิศวกรรมซอฟต์แวร์กับ Simon Peyton Jones สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Haskell: ตอนที่ 108: Simon Peyton Jones ใน Functional Programming และ Haskell


8
ประโยชน์หลักอีกอย่างที่เป็นไปได้ของ F # (ขึ้นอยู่กับสถานการณ์) คือไม่ขี้เกียจซึ่งหมายความว่าเส้นโค้งการเรียนรู้สำหรับการหาเหตุผลเกี่ยวกับพฤติกรรมของเวลาอวกาศจะง่ายกว่ามากสำหรับทุกคน
cjs

5
ลิงค์ตรง se-radio ตอนที่ 108 (Simon Peyton Jones): se-radio.net/podcast/2008-08/…
Herrmann

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

12
@JonHarrop: นั่นคือคำแถลงเกี่ยวกับอัลกอริทึมซึ่งไม่เกี่ยวข้องกับการบังคับใช้การปรับแต่งคอมไพเลอร์ ภาษาที่บังคับใช้โดยทั่วไปจะอนุญาตให้คุณเขียนรหัสที่ไม่บริสุทธิ์อย่างชัดเจนหากคุณต้องการจริงๆ (ถ้าไม่มีอะไรให้ใช้ FFI เพื่อเรียก C) คอมไพเลอร์สามารถใช้การแปลงรหัสได้อย่างอิสระมากขึ้นเมื่อไม่ได้ผูกมัดเพื่อรักษาลำดับของผลข้างเคียง (ไม่ทราบ) ในภาษาที่ "สนับสนุนความบริสุทธิ์" คุณเขียนโค้ดที่คล้ายกันเป็นส่วนใหญ่ดังนั้นการเพิ่มประสิทธิภาพเดียวกันจะใช้ได้เพียง แต่อาจทำให้ผลข้างเคียงเป็นโมฆะ (ซึ่งไม่มี แต่คอมไพเลอร์ไม่สามารถสันนิษฐานได้)
เบ็น

3
@JonHarrop เมื่อไหร่ที่ฉันอ้างว่าเป็นอัลกอริทึมทั้งหมด ไม่ว่าในกรณีใดเรากำลังเปรียบเทียบ Haskell และ F # ไม่ใช่ Haskell และ C F # เป็นภาษาที่ "ได้รับการสนับสนุน" ดังนั้นคุณจึงมักเขียนโค้ดที่บริสุทธิ์ ทั้งหมดที่ฉันอ้างคือโค้ดเดียวกันนั้นมักจะสามารถปรับให้เหมาะสมได้ดีกว่าโดยคอมไพเลอร์ในการตั้งค่า "บังคับใช้ความบริสุทธิ์" เนื่องจากคอมไพเลอร์ F # ต้องถือว่าการโทรมีผลข้างเคียง คุณกำลังพูดถึงการเขียนโค้ดใหม่เพื่อใช้อัลกอริทึมอื่น (อันที่ขึ้นอยู่กับผลข้างเคียง) ฉันกำลังพิจารณาเกี่ยวกับ "ความสามารถในการเพิ่มประสิทธิภาพ" ของรหัสบริสุทธิ์ใน F # vs Haskell
เบ็น

53

ความแตกต่างใหญ่:

  • แพลตฟอร์ม
  • การวางแนววัตถุ
  • ความเกียจคร้าน

ความเหมือนสำคัญกว่าความแตกต่าง โดยทั่วไปคุณควรใช้ F # หากคุณใช้. NET อยู่แล้วไม่เช่นนั้น Haskell นอกจากนี้ OO และความเกียจคร้านยังหมายความว่า F # อยู่ใกล้กับสิ่งที่คุณ (อาจ) รู้อยู่แล้วดังนั้นจึงน่าจะเรียนรู้ได้ง่ายกว่า

แพลตฟอร์ม: Haskell มีรันไทม์ของตัวเอง F # ใช้. NET ฉันไม่รู้ว่าความแตกต่างของประสิทธิภาพคืออะไรแม้ว่าฉันจะสงสัยว่าโค้ดเฉลี่ยนั้นใกล้เคียงกันก่อนการเพิ่มประสิทธิภาพ F # มีข้อได้เปรียบหากคุณต้องการไลบรารี. NET

การวางแนววัตถุ: F # มี OO และระมัดระวังอย่างยิ่งเพื่อให้แน่ใจว่าคลาส. NET นั้นใช้งานง่ายแม้ว่ารหัสของคุณจะไม่ใช่ OO ก็ตาม Haskell มีคลาสประเภทที่ให้คุณทำบางอย่างเช่น OO ได้ในแบบแปลก ๆ พวกเขาเหมือนกับ Ruby mixins ที่ผสมกับ Common Lisp ฟังก์ชันทั่วไป มันเหมือนกับอินเตอร์เฟส Java / C # เล็กน้อย

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

ความแตกต่างเล็กน้อย:

  • ไวยากรณ์: Haskell มีไวยากรณ์ที่ดีกว่าเล็กน้อยในความคิดของฉัน มันสั้นและสม่ำเสมอกว่าเล็กน้อยและฉันชอบการประกาศประเภทในบรรทัดแยกต่างหาก YMMV.
  • เครื่องมือ: F # มีการรวม Visual Studio ที่ยอดเยี่ยมหากคุณชอบสิ่งนั้น Haskell ยังมีปลั๊กอิน Visual Studio รุ่นเก่าแต่ฉันไม่คิดว่ามันจะออกจากเบต้า Haskell มีโหมด emacs ที่เรียบง่ายและคุณอาจใช้โหมด tuareg ของ OCamlเพื่อแก้ไข F #
  • ผลข้างเคียง: ทั้งสองภาษาทำให้เห็นได้ชัดเจนเมื่อคุณกำลังกลายพันธุ์ตัวแปร แต่คอมไพเลอร์ของ Haskell ยังบังคับให้คุณทำเครื่องหมายผลข้างเคียงทุกครั้งที่ใช้ ความแตกต่างในทางปฏิบัติคือคุณต้องตระหนักให้มากขึ้นเมื่อคุณใช้ไลบรารีที่มีผลข้างเคียงเช่นกัน

1
ดูประสิทธิภาพการทำงาน ไม่แน่ใจว่าถูกต้องแค่ไหน
nawfal

35

F # เป็นส่วนหนึ่งของตระกูลภาษา ML และอยู่ใกล้กับ OCaml มาก คุณอาจต้องการที่จะอ่านการสนทนานี้บนความแตกต่างระหว่าง Haskell และ OCaml


6
แม้ว่าลิงก์นี้อาจตอบคำถามได้ แต่ควรรวมส่วนสำคัญของคำตอบไว้ที่นี่และระบุลิงก์เพื่อการอ้างอิง คำตอบแบบลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าที่เชื่อมโยงเปลี่ยนไป - จากรีวิว
mirabilos

33

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

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

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

เช่นกันบางครั้ง F # อาจทำงานได้น้อยลงเล็กน้อยหรือดูอึดอัดมากขึ้น (จากมุมมองการเขียนโปรแกรมเชิงฟังก์ชัน) เมื่อคุณเชื่อมต่อกับแพลตฟอร์ม / ไลบรารี. NET เนื่องจากไลบรารีได้รับการออกแบบอย่างชัดเจนจากมุมมอง OO

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

อีกสองประเด็นที่ไม่เกี่ยวข้อง:

Haskell มีไวยากรณ์ที่ดีกว่าเล็กน้อยซึ่งไม่น่าแปลกใจเนื่องจากนักออกแบบของ Haskell รู้จัก ML ค่อนข้างดี อย่างไรก็ตามไวยากรณ์ 'light' ของ F # ไปได้ไกลในการปรับปรุงไวยากรณ์ ML ดังนั้นจึงไม่มีช่องว่างขนาดใหญ่ที่นั่น

ในแง่ของแพลตฟอร์ม F # คือ. NET; มันจะทำงานกับโมโนได้ดีแค่ไหนฉันไม่รู้ GHC รวบรวมกับรหัสเครื่องด้วยรันไทม์ของตัวเองซึ่งทำงานได้ดีทั้งใน Windows และ Unix ซึ่งเปรียบเทียบกับ. NET ในลักษณะเดียวกันที่กล่าวว่า C ++ ทำ นี่อาจเป็นข้อได้เปรียบในบางสถานการณ์โดยเฉพาะอย่างยิ่งในแง่ของความเร็วและการเข้าถึงเครื่องระดับล่าง (ตัวอย่างเช่นฉันไม่มีปัญหาในการเขียนเซิร์ฟเวอร์ DDE ใน Haskell / GHC ฉันไม่คิดว่าคุณจะทำได้ในภาษา. NET ใด ๆ และไม่ว่า MS จะไม่ต้องการให้คุณทำเช่นนั้นอย่างแน่นอน)


2

อย่างหนึ่งฉันจะบอกว่าข้อได้เปรียบหลักคือ F # รวบรวมกับแพลตฟอร์ม. NET ซึ่งทำให้ง่ายต่อการปรับใช้บน windows ฉันเคยเห็นตัวอย่างที่อธิบายโดยใช้ F # ร่วมกับ ASP.NET เพื่อสร้างเว็บแอปพลิเคชัน ;-)

ในทางกลับกัน Haskell อยู่กับ waaaaay มานานกว่าแล้วดังนั้นฉันคิดว่ากลุ่มคนที่เป็นผู้เชี่ยวชาญด้านภาษานั้นมีจำนวนมาก

สำหรับ F # ฉันเคยเห็นการใช้งานจริงเพียงครั้งเดียวซึ่งเป็นการพิสูจน์ความเป็นเอกฐานของระบบปฏิบัติการแนวคิด ฉันได้เห็นการใช้งาน Haskell ในโลกแห่งความเป็นจริงมากขึ้น


4
F # มีเรื่องราวความสำเร็จที่สำคัญหลายเรื่อง (Halo 3, AdCenter, F # for Visualization) ซึ่งทำให้สิ่งที่ใกล้เคียงที่สุดของ Haskell มีต่อเรื่องราวความสำเร็จ (Darcs)
JD

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