Tôi đang cố dịch mũi tên của thư viện lõi Haskell thành F # (tôi nghĩ đó là một bài tập tốt để hiểu các Mũi tên và F # tốt hơn, và tôi có thể sử dụng chúng trong một dự án mà tôi đang làm việc). dịch trực tiếp là không thể do sự khác biệt trong mô hình. Haskell sử dụng các loại-class để thể hiện công cụ này, nhưng tôi không chắc chắn những gì F # xây dựng bản đồ tốt nhất các chức năng của loại-class với các thành ngữ của F #. Tôi có một vài suy nghĩ, nhưng đã tìm ra cách tốt nhất để đưa nó lên đây và xem những gì được coi là gần nhất trong chức năng.Làm cách nào để dịch lớp loại Haskell sang F #?
Đối với đám đông tl; dr: Làm cách nào để dịch các loại lớp (thành ngữ Haskell) thành mã # idiomatic?
Đối với những người chấp nhận lời giải thích dài của tôi:
Mã này từ tiêu chuẩn lib Haskell là một ví dụ về những gì tôi đang cố gắng để dịch:
class Category cat where
id :: cat a a
comp :: cat a b -> cat b c -> cat a c
class Category a => Arrow a where
arr :: (b -> c) -> a b c
first :: a b c -> a (b,d) (c,d)
instance Category (->) where
id f = f
instance Arrow (->) where
arr f = f
first f = f *** id
Cố gắng 1: Modules, Simple loại , Hãy Bindings
Ảnh đầu tiên của tôi ở đây là chỉ cần ánh xạ mọi thứ qua trực tiếp bằng Mô-đun cho tổ chức, như:
type Arrow<'a,'b> = Arrow of ('a -> 'b)
let arr f = Arrow f
let first f = //some code that does the first op
Đó là công trình, nhưng nó bị mất tính đa hình, vì tôi không triển khai Danh mục và không thể triển khai dễ dàng nhiều Mũi tên chuyên biệt hơn.
Cố gắng 1a: Tinh chỉnh sử dụng chữ ký và các loại
Một cách để sửa chữa một số vấn đề với Cố gắng 1 là sử dụng một tập tin .fsi để xác định các phương pháp (vì vậy các loại thực thi dễ dàng hơn) và sử dụng một số đơn giản loại chỉnh để chuyên.
type ListArrow<'a,'b> = Arrow<['a],['b]>
//or
type ListArrow<'a,'b> = LA of Arrow<['a],['b]>
Nhưng không thể sử dụng lại tệp fsi (để thực thi các loại hàm ràng buộc) cho các triển khai khác và loại đổi tên/đóng gói rất khó.
Cố gắng 2: mô hình đối tượng và giao diện
Hợp lý hoá mà F # được xây dựng để được OO cũng có, có thể là một hệ thống phân cấp loại là đúng cách để làm điều này.
type IArrow<'a,'b> =
abstract member comp : IArrow<'b,'c> -> IArrow<'a,'c>
type Arrow<'a,'b>(func:'a->'b) =
interface IArrow<'a,'b> with
member this.comp = //fun code involving "Arrow (fun x-> workOn x) :> IArrow"
Bên cạnh bao nhiêu một nỗi đau nó có thể để có được những gì cần được phương pháp tĩnh (như comp và nhà khai thác khác) để hoạt động như phương pháp dụ, cũng có nhu cầu upCast một cách rõ ràng các kết quả. Tôi cũng không chắc chắn rằng phương pháp này vẫn đang nắm bắt được sự thể hiện đầy đủ của đa hình loại lớp. Nó cũng làm cho nó khó khăn để sử dụng những thứ PHẢI là phương pháp tĩnh.
Cố gắng 2a: Tinh chỉnh sử dụng phần mở rộng loại
Vì vậy, thêm một sự tinh tế tiềm năng để khai báo các giao diện như trần càng tốt, sau đó sử dụng phương pháp mở rộng thêm chức năng cho tất cả các loại thực hiện.
type IArrow<'a,'b> with
static member (&&&) f = //code to do the fanout operation
Ah, nhưng điều này khiến tôi sử dụng một phương pháp cho tất cả các loại IArrow.Nếu tôi muốn có một chút khác biệt (& & &) đối với ListArrows, tôi có thể làm gì? Tôi chưa thử phương pháp này, nhưng tôi đoán tôi có thể che bóng (& & &) hoặc ít nhất cung cấp phiên bản chuyên biệt hơn, nhưng tôi cảm thấy mình không thể thực thi việc sử dụng biến thể đúng.
Help me
Vì vậy, những gì tôi phải làm gì đây? Tôi cảm thấy như OO nên đủ mạnh để thay thế các loại lớp, nhưng tôi dường như không thể tìm ra cách để làm điều đó xảy ra trong F #. Có bất kỳ nỗ lực nào của tôi không? Có ai trong số họ "tốt như nó được" và đó sẽ phải là đủ tốt?
"Làm cách nào để dịch các loại lớp (thành ngữ Haskell) thành mã # idiomatic?" Ý tưởng tồi. Bạn nên xem xét vấn đề * * mà bạn đang cố giải quyết thay vì giải pháp đã xảy ra để sử dụng các lớp kiểu và tìm ra cách giải quyết nó bằng cách sử dụng tính năng mà F # cung cấp. –
@Jon Harrop Đó là điểm của câu hỏi. Haskell giải quyết hàng chục vấn đề với các loại lớp, và tôi muốn biết những gì các lựa chọn thay thế F # đã được giải quyết một lớp * tương tự của các vấn đề.Ngoài ra các cổng mũi tên không phải là để giải quyết bất kỳ vấn đề, nó chỉ là một "Tôi nghĩ rằng nó sẽ được vui vẻ để tìm hiểu thêm về mũi tên" hoạt động. – CodexArcanum
Sau đó, tôi nghĩ rằng nó sẽ thực sự có giá trị nếu bạn có thể giải thích một số vấn đề mà các lớp học giải quyết và hỏi mọi người cách họ sẽ giải quyết các vấn đề tương tự trong F #. –