2012-11-09 30 views

Trả lời

18

Câu trả lời tùy thuộc vào vấn đề bạn đang cố giải quyết. F # không có typeclasses và GADT, vì vậy không có ánh xạ trực tiếp. Tuy nhiên, F # có cơ chế khác nhau mà bạn sẽ sử dụng để giải quyết vấn đề mà bạn thường giải quyết trong Haskell sử dụng GADTs và typeclasses:

  • Nếu bạn muốn thể hiện cấu trúc đối tượng và có thể thêm triển khai bê tông mới với hành vi khác nhau, thì bạn thường có thể sử dụng OO và giao diện chuẩn.

  • Nếu bạn muốn viết mã số chung, bạn có thể sử dụng các ràng buộc thành viên tĩnh (here is an example), có lẽ là kỹ thuật cơ chế gần nhất để nhập các lớp.

  • Nếu bạn muốn viết mã chung nâng cao hơn (như máy in hoặc trình phân tích cú pháp phổ biến) thì bạn thường có thể sử dụng các khả năng powerful F# runtime reflection.

  • Nếu bạn cần tham số hóa mã bằng một tập hợp các hàm (thực hiện các hoạt động phụ khác nhau theo yêu cầu của mã) thì bạn có thể thực hiện một giao diện như giao diện @pad.

Ngoài ra còn có một cách để emulate Haskell type classes in F#, nhưng điều này thường không phải là một giải pháp F # thành ngữ, bởi vì F phong cách # lập trình khác với phong cách Haskell trong một số cách khác nhau. Một cách sử dụng khá chuẩn là xác định các toán tử quá tải (xem this SO answer).

Ở cấp meta, yêu cầu tương đương với tính năng X bằng ngôn ngữ khác thường dẫn đến một cuộc thảo luận bị nhầm lẫn, vì X có thể được sử dụng để giải quyết vấn đề A, B, C bằng một ngôn ngữ cung cấp các tính năng khác nhau để giải quyết các vấn đề tương tự (hoặc một số vấn đề có thể không tồn tại).

8

Trong F #, bạn thường sử dụng interfacesinheritance cho các mục đích này.

Vì ví dụ, đây là một typeclass đơn giản sử dụng giao diện và object expressions:

/// Typeclass 
type MathOps<'T> = 
    abstract member Add : 'T -> 'T -> 'T 
    abstract member Mul : 'T -> 'T -> 'T 

/// An instance for int 
let mathInt = 
    { new MathOps<int> with 
     member __.Add x y = x + y 
     member __.Mul x y = x * y } 

/// An instance for float 
let mathFloat = 
    { new MathOps<float> with 
     member __.Add x y = x + y 
     member __.Mul x y = x * y } 

let XtimesYplusZ (ops: MathOps<'T>) x y z = 
    ops.Add (ops.Mul x y) z 

printfn "%d" (XtimesYplusZ mathInt 3 4 1) 
printfn "%f" (XtimesYplusZ mathFloat 3.0 4.0 1.0) 

Nó có thể không trông rất đẹp, nhưng đó là F # cách -ish để làm điều đó. Đối với một giải pháp giống như Haskell sử dụng từ điển hoạt động, bạn có thể xem this nice answer.

+1

Đây là một ví dụ gây hiểu nhầm, bởi vì đối với mã số bạn chỉ có thể viết 'let inline XtimesYplusZ x y z = (x * y) + z' và' XtimesYplusZ 3 4 1' và 'XtimesYplusZ 3.0 4.0 1.0' sẽ hoạt động. Nhưng tất nhiên, trong một kịch bản khác, mã dựa trên phong cách bạn đang trình diễn sẽ là một cách tốt để mô hình hóa kiểu tham số hóa này bằng các phép toán. Tôi đoán đó là những gì tôi có ý nghĩa bằng cách nói rằng có những cách tiếp cận khác nhau cho các vấn đề khác nhau được giải quyết bởi các lớp loại trong Haskell. –

+1

Có, tôi đã cố gắng tìm một ví dụ điển hình. Những gì tôi muốn chứng minh là phong cách mã hóa chỉ; nó không phải là về mã số. – pad

Các vấn đề liên quan