2012-06-13 27 views
8

Làm cách nào để làm điều này haskell trong F # sạch?Phiên bản F # của kết hợp mẫu haskell

add 1 2 x = 3 + x 
add 1 x y = 1 + x + y 
add z x y = z + x + y 
+0

Tôi không biết haskell, mục tiêu ở đây là gì? Điều này trông giống như một tối ưu hóa mà trình biên dịch sẽ nắm bắt và giải quyết. Tôi nghĩ rằng cố gắng để viết một tương đương trong F # với mô hình phù hợp sẽ chậm hơn. Bạn đang cố gắng đạt được điều gì? – gjvdkamp

+2

gjvdkamp, ​​nó không phải là một tối ưu hóa, một thiết bị cú pháp của nó mà làm cho mỗi trường hợp dễ đọc hơn. 'f 1 = x; f 2 = y' được dịch thành 'f a = case a của 1 -> x; 2 -> y' - http://www.haskell.org/onlinereport/decls.html#sect4.4.3.1 –

Trả lời

21

Bạn không thể quá tải chức năng riêng của mình, nhưng bạn có thể sử dụng mô hình kết hợp trực tiếp:

let add z x y =    // curried multiple parameters 
    match z, x, y with  // convert to three-tuple to match on 
    | 1, 2, x -> 3 + x 
    | 1, x, y -> 1 + x + y 
    | z, x, y -> z + x + y 

Việc sử dụng như mong đợi: add 1 2 3

Nếu bạn sẵn sàng để sử dụng tuples là đối số (ví dụ: forgo currying và partial application), bạn thậm chí có thể viết nó nhanh hơn:

let add =      // expect three-tuple as first (and only) parameter 
    function     // use that one value directly to match on 
    | 1, 2, x -> 3 + x 
    | 1, x, y -> 1 + x + y 
    | z, x, y -> z + x + y 

Cách sử dụng bây giờ là: add (1, 2, 3)

+0

Cảm ơn! Tôi đã tìm kiếm các ví dụ phù hợp với mẫu f # và không có ai khớp nhiều hơn một tham số trong các mẫu, tôi đã được đưa ra ấn tượng rằng bạn không thể làm điều này. –

+0

@Jmymy: Về mặt kỹ thuật, một bộ dữ liệu duy nhất đang được kết hợp ở đây, vì vậy bạn không sai ... – ildjarn

+0

@ildjarn: chỉ trong ví dụ thứ hai mà không phải là những gì tôi sẽ sử dụng bởi vì bạn mất currying/một phần ứng dụng mà tôi cảm thấy là một trong những phần có lợi nhất của các ngôn ngữ này –

8

Nhớ lại trong Haskell rằng general form of functions như một danh sách các tờ khai với các mẫu:

f pat1 ... = e1 
f pat2 ... = e2 
f pat3 ... = e3 

chỉ đường cho việc phân tích case:

f x1 .. xn = case (x1, .. xn) of 
       (pat1, ..., patn) -> e1 
       (pat2, ..., patn) -> e2 
       (pat3, ..., patn) -> e3 

nên bản dịch tương tự có thể được thực hiện với các ngôn ngữ khác có khớp mẫu nhưng không có mẫu cấp khai báo.

+0

Tôi nhận ra nó chỉ là một trường hợp, nhưng lý do đường tồn tại trong haskell là để làm sạch, tôi đã hy vọng một cái gì đó tương tự tồn tại trong f #, và như yamen chỉ ra, phù hợp trong f # có thể làm việc trong cùng một thời trang –

5

Đây hoàn toàn là cú pháp. Ngôn ngữ như Haskell, Standard ML và Mathematica cho phép bạn viết ra trường hợp kết hợp khác nhau như thể chúng là các chức năng khác nhau:

factorial 0 = 1 
factorial 1 = 1 
factorial n = n * factorial(n-1) 

trong khi các ngôn ngữ như OCaml và F # yêu cầu bạn phải có một định nghĩa hàm đơn và sử dụng match hoặc tương đương trong cơ thể của nó:

let factorial = function 
    | 0 -> 1 
    | 1 -> 1 
    | n -> n * factorial(n-1) 

Lưu ý rằng bạn không cần phải sao chép các tên hàm hơn và hơn nữa sử dụng cú pháp này và bạn có thể yếu tố trường hợp trận đấu dễ dàng hơn:

let factorial = function 
    | 0 | 1 -> 1 
    | n -> n * factorial(n-1) 

Như yamen đã viết, làm currying với let f a b = match a, b with ... trong F #.

Trong việc thực hiện cây đỏ-đen cổ điển, tôi tìm ra sự trùng lặp của tên hàm và hai bên cánh tay phải trong Standard ML và Haskell khá xấu xí:

balance :: RB a -> a -> RB a -> RB a 
balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d) 
balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d) 
balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d) 
balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d) 
balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d) 
balance a x b = T B a x b 

so với tương đương OCaml hoặc F #:

let balance = function 
    | B, z, (T(R, y, T(R, x, a, b), c) | T(R, x, a, T(R, y, b, c))), d 
    | B, x, a, (T(R, z, T(R, y, b, c), d) | T(R, y, b, T(R, z, c, d))) -> 
     T(R, y, T(B, x, a, b), T(B, z, c, d)) 
    | a, b, c, d -> T(a, b, c, d) 
Các vấn đề liên quan