Sự khác biệt chính giữa Haskell và F # là gì? [đóng cửa]


135

Tôi đã tìm kiếm trên Internet để so sánh giữa F #Haskell nhưng không tìm thấy điều gì thực sự chính xác. Sự khác biệt chính là gì và tại sao tôi muốn chọn cái này hơn cái kia?


1
Điều tốt đẹp về F # là do mô hình hỗn hợp của nó, nó cung cấp một điểm khởi đầu tốt hơn cho lập trình viên OO. Anh ta dần dần có thể bắt kịp tốc độ với tư duy chức năng và vẫn tiếp tục sử dụng các thư viện OO quen thuộc như anh ta đã làm trong C #. Haskell buộc toàn bộ enchilada chức năng vào bạn cùng một lúc.
Mario

Điều quan trọng cần lưu ý là F # không phải là một ngôn ngữ lập trình chức năng. Tuy nhiên, nó được áp dụng khá nhiều từ FP, vì vậy có thể tìm thấy nhiều điểm tương đồng, nhưng chủ yếu tôi muốn nói rằng chúng hoàn toàn là các ngôn ngữ khác nhau.
MasterMastic

Câu trả lời:


128

Haskell là một ngôn ngữ chức năng "thuần túy", trong đó F # có các khía cạnh của cả ngôn ngữ mệnh lệnh / OO và ngôn ngữ chức năng. Haskell cũng có đánh giá lười biếng, điều này khá hiếm trong số các ngôn ngữ chức năng.

Những điều này có nghĩa là gì? Một ngôn ngữ hàm thuần túy, có nghĩa là không có tác dụng phụ (hoặc thay đổi ở trạng thái được chia sẻ, khi một hàm được gọi), có nghĩa là bạn được đảm bảo rằng nếu bạn gọi f (x), không có gì khác xảy ra ngoài việc trả về một giá trị từ hàm, chẳng hạn như đầu ra bảng điều khiển, đầu ra cơ sở dữ liệu, thay đổi đối với biến toàn cục hoặc biến tĩnh .. và mặc dù Haskell có thể có các hàm không thuần túy (thông qua monads), nhưng nó phải được ngụ ý 'rõ ràng' thông qua khai báo.

Các ngôn ngữ chức năng thuần túy và lập trình 'Không có tác dụng phụ' đã trở nên phổ biến gần đây vì nó có lợi cho sự đồng thời đa lõi, vì khó bị sai hơn nhiều khi không có trạng thái được chia sẻ, thay vì vô số khóa & semaphores.

Đánh giá lười biếng là nơi một chức năng KHÔNG được đánh giá cho đến khi nó thực sự cần thiết. nghĩa là có thể tránh được nhiều thao tác khi không cần thiết. Hãy nghĩ về điều này trong một mệnh đề C # if cơ bản như sau:

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

Nếu IsSomethingTrue()sai thì AnotherThingTrue()phương thức không bao giờ được đánh giá.

Mặc dù Haskell là một ngôn ngữ tuyệt vời, nhưng lợi ích chính của F # (vào thời điểm hiện tại) là nó nằm trên CLR. Điều này cho phép lập trình polyglot. Một ngày nào đó, bạn có thể viết giao diện người dùng web của mình trong ASP.net MVC, logic nghiệp vụ của bạn trong C #, các thuật toán cốt lõi của bạn trong F # và các bài kiểm tra đơn vị của bạn trong Ironruby .... Tất cả đều nằm trong khuôn khổ .Net.

Nghe radio Kỹ thuật phần mềm với Simon Peyton Jones để biết thêm thông tin về Haskell: Tập 108: Simon Peyton Jones về Lập trình chức năng và Haskell


8
Một lợi ích chính tiềm năng khác của F # (tùy thuộc vào tình huống) là nó không lười biếng, có nghĩa là đường cong học tập để lý luận về hành vi không-thời gian sẽ đơn giản hơn nhiều đối với hầu hết mọi người.
cjs

5
Liên kết trực tiếp đến se-radio Tập 108 (Simon Peyton Jones): se-radio.net/podcast/2008-08/…
Herrmann

9
Một tính năng khác đáng chỉ ra là một ngôn ngữ thực thi lập trình thuần túy, trình biên dịch có nhiều quyền tự do hơn cho nhiều tối ưu hóa. Các ngôn ngữ như F # khuyến khích sự tinh khiết nhưng vẫn cho phép bỏ qua các hoạt động không tinh khiết chưa được kiểm tra bên trong bất kỳ khối mã nào bị mất trên một số tối ưu hóa tiềm năng, vì trình biên dịch buộc phải giả định mọi lệnh gọi đều chứa các tác dụng phụ cần thiết.
Ben

12
@JonHarrop: Đó là một tuyên bố về các thuật toán, không liên quan đến khả năng áp dụng tối ưu hóa trình biên dịch. Các ngôn ngữ thuần túy bắt buộc thường cho phép bạn viết mã không tinh khiết rõ ràng nếu bạn thực sự cần (nếu không có gì khác, sử dụng FFI để gọi C). Trình biên dịch có thể áp dụng các phép biến đổi mã một cách tự do hơn khi nó không bị ràng buộc phải bảo toàn thứ tự của các tác dụng phụ (không xác định). Trong các ngôn ngữ "độ tinh khiết được khuyến khích", bạn viết hầu hết mã tương tự để áp dụng các tối ưu hóa giống nhau, chỉ chúng có thể làm mất hiệu lực các tác dụng phụ (không có ở đó, nhưng trình biên dịch không thể giả định điều đó).
Ben

3
@JonHarrop Khi tôi khẳng định chúng đều là thuật toán? Trong mọi trường hợp, chúng tôi đang so sánh Haskell và F #, không phải Haskell và C. F # là ngôn ngữ "được khuyến khích thuần túy", vì vậy bạn thường viết mã thuần túy. Tất cả những gì tôi khẳng định là cùng một mã chính xác thường có thể được trình biên dịch tối ưu hóa tốt hơn trong cài đặt "độ tinh khiết được thực thi", bởi vì trình biên dịch F # phải giả định rằng các lệnh gọi có tác dụng phụ. Bạn đang nói về việc viết lại mã để sử dụng một thuật toán khác (một thuật toán phụ thuộc vào các tác dụng phụ); Tôi đang nói về "tính tối ưu" của mã thuần trong F # vs Haskell.
Ben

53

Sự khác biệt lớn:

  • Nền tảng
  • Hướng đối tượng
  • Lười biếng

Những điểm tương đồng quan trọng hơn những điểm khác biệt. Về cơ bản, bạn nên sử dụng F # nếu bạn đang sử dụng .NET, Haskell nếu không. Ngoài ra, OO và lười biếng có nghĩa là F # gần hơn với những gì bạn (có thể) đã biết, vì vậy nó có thể dễ học hơn.

Nền tảng: Haskell có thời gian chạy riêng, F # sử dụng .NET. Tôi không biết sự khác biệt về hiệu suất là gì, mặc dù tôi nghi ngờ mã trung bình là giống nhau trước khi tối ưu hóa. F # có lợi thế nếu bạn cần các thư viện .NET.

Hướng đối tượng: F # có OO và rất cẩn thận để đảm bảo rằng các lớp .NET dễ sử dụng ngay cả khi mã của bạn không phải là OO. Haskell có các lớp kiểu cho phép bạn làm điều gì đó giống như OO, theo một cách kỳ lạ. Chúng giống như các mixin của Ruby được lai với các hàm chung của Common Lisp. Chúng hơi giống giao diện Java / C #.

Lười biếng: Haskell lười biếng, F # thì không. Sự lười biếng cho phép một số thủ thuật hay và làm cho một số thứ trông có vẻ chậm nhưng lại thực thi nhanh chóng. Nhưng tôi thấy khó hơn rất nhiều để đoán mã của mình sẽ chạy nhanh như thế nào. Cả hai ngôn ngữ đều cho phép bạn sử dụng mô hình khác, bạn chỉ cần trình bày rõ ràng về mô hình đó trong mã của mình.

Sự khác biệt nhỏ:

  • Cú pháp: Theo tôi Haskell có cú pháp đẹp hơn một chút. Nó ngắn gọn và thông thường hơn một chút, và tôi thích khai báo các loại trên một dòng riêng biệt. YMMV.
  • Công cụ: F # có tích hợp Visual Studio tuyệt vời, nếu bạn thích điều đó. Haskell cũng có một plugin Visual Studio cũ hơn , nhưng tôi không nghĩ nó đã ra khỏi bản beta. Haskell có một chế độ emacs đơn giản và bạn có thể sử dụng chế độ kéo co của OCaml để chỉnh sửa F #.
  • Tác dụng phụ: Cả hai ngôn ngữ đều làm cho nó khá rõ ràng khi bạn đang thay đổi các biến. Nhưng trình biên dịch của Haskell cũng buộc bạn phải đánh dấu các tác dụng phụ bất cứ khi nào bạn sử dụng chúng. Sự khác biệt thực tế là bạn phải nhận thức được nhiều hơn khi bạn sử dụng các thư viện với các tác dụng phụ.

1
xem để biết hiệu suất . Không chắc nó hợp pháp như thế nào
nawfal

35

F # là một phần của họ ngôn ngữ ML và rất gần với OCaml. Bạn có thể muốn đọc cuộc thảo luận này về sự khác biệt giữa Haskell và OCaml .


6
Mặc dù liên kết này có thể trả lời câu hỏi, nhưng tốt hơn hết bạn nên đưa các phần thiết yếu của câu trả lời vào đây và cung cấp liên kết để tham khảo. Các câu trả lời chỉ có liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi. - Từ xét
mirabilos

33

Một sự khác biệt lớn, có lẽ là kết quả của sự tinh khiết nhưng tôi ít thấy được đề cập đến, là việc sử dụng phổ biến các monads. Như đã được chỉ ra thường xuyên, các monads có thể được xây dựng bằng hầu hết mọi ngôn ngữ, nhưng cuộc sống sẽ thay đổi rất nhiều khi chúng được sử dụng tràn lan khắp các thư viện và chính bạn sử dụng chúng.

Đơn nguyên cung cấp một cái gì đó được nhìn thấy theo một cách hạn chế hơn nhiều trong các ngôn ngữ khác: tính trừu tượng của điều khiển luồng. Chúng là những cách cực kỳ hữu ích và thanh lịch để làm mọi thứ, và một năm Haskell đã thay đổi hoàn toàn cách tôi lập trình, giống như cách mà việc chuyển từ lập trình bắt buộc sang lập trình OO nhiều năm trước đã thay đổi nó, hoặc sau đó nhiều năm. bằng cách sử dụng các chức năng bậc cao hơn đã làm.

Thật không may, không có cách nào trong một không gian như thế này để cung cấp đủ hiểu biết để cho bạn thấy sự khác biệt là gì. Trong thực tế, không có số lượng văn bản sẽ làm điều đó; đơn giản là bạn phải dành đủ thời gian học và viết mã để có được sự hiểu biết thực sự.

Ngoài ra, F # đôi khi có thể trở nên kém chức năng hơn một chút hoặc khó xử lý hơn (từ quan điểm lập trình chức năng) khi bạn giao diện với nền tảng / thư viện .NET, vì các thư viện rõ ràng được thiết kế theo quan điểm OO.

Vì vậy, bạn có thể cân nhắc quyết định của mình theo cách này: bạn đang muốn thử một trong những ngôn ngữ này để có được sự cải thiện nhanh chóng, tương đối nhỏ hay bạn sẵn sàng bỏ thêm thời gian và nhận được ít lợi ích tức thì hơn cho một thứ lớn dài hạn. (Hoặc, ít nhất, nếu bạn không nhận được thứ gì đó lớn hơn, thì khả năng dễ dàng chuyển sang thứ khác nhanh chóng?) Nếu cái trước, F # là lựa chọn của bạn, nếu cái sau, Haskell.

Một số điểm không liên quan khác:

Haskell có cú pháp đẹp hơn một chút, điều này không có gì ngạc nhiên, vì các nhà thiết kế của Haskell biết ML khá rõ. Tuy nhiên, cú pháp 'light' của F # đi một chặng đường dài hướng tới việc cải thiện cú pháp ML, vì vậy không có khoảng cách lớn ở đó.

Về nền tảng, F # tất nhiên là .NET; Tôi không biết điều đó sẽ hoạt động tốt như thế nào trên Mono. GHC biên dịch thành mã máy với thời gian chạy riêng của nó, hoạt động tốt trong cả Windows và Unix, so với .NET theo cùng một cách, chẳng hạn như C ++. Đây có thể là một lợi thế trong một số trường hợp, đặc biệt là về tốc độ và quyền truy cập máy cấp thấp hơn. (Ví dụ: tôi không gặp vấn đề gì khi viết máy chủ DDE trong Haskell / GHC; tôi không nghĩ rằng bạn có thể làm điều đó bằng bất kỳ ngôn ngữ .NET nào, và bất kể, MS chắc chắn không muốn bạn làm điều đó.)


2

Vâng, tôi muốn nói một lợi thế chính là F # biên dịch dựa trên nền tảng .NET giúp dễ dàng triển khai trên windows. Tôi đã xem các ví dụ giải thích bằng cách sử dụng F # kết hợp với ASP.NET để xây dựng các ứng dụng web ;-)

Mặt khác, Haskell đã tồn tại lâu hơn, vì vậy tôi nghĩ rằng nhóm những người là chuyên gia thực sự về ngôn ngữ đó lớn hơn rất nhiều.

Đối với F #, cho đến nay, tôi mới chỉ thấy một triển khai thực sự, đó là bằng chứng Đặc biệt của khái niệm OS. Tôi đã thấy nhiều triển khai Haskell trong thế giới thực hơn.


4
F # đã có một số câu chuyện thành công lớn (Halo 3, AdCenter, F # cho Hình ảnh hóa), vượt xa điều gần nhất mà Haskell có trong một câu chuyện thành công (Darcs).
JD

Đáng chỉ ra rằng có những mặt trái của điều này, tất nhiên. (Giới hạn CLR)
MasterMastic
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.