2009-11-30 5 views
8

Bạn có thể vượt qua trong một hoạt động như "chia cho 2" hoặc "trừ 1" chỉ sử dụng một nhà điều hành áp dụng một phần, trong đó "thêm 1" trông như thế này:F # thông qua một nhà điều hành với đối số cho hàm

List.map ((+) 1) [1..5];; //equals [2..6] 
// instead of having to write: List.map (fun x-> x+1) [1..5] 

Điều đang xảy ra là 1 đang được áp dụng cho (+) làm đối số đầu tiên và mục danh sách đang được áp dụng làm đối số thứ hai. Để thêm và nhân, thứ tự đối số này không quan trọng.

Giả sử tôi muốn trừ đi 1 từ mọi phần tử (điều này có lẽ sẽ là một người mới bắt đầu sai lầm phổ biến):

List.map ((-) 1) [1..5];; //equals [0 .. -4], the opposite of what we wanted 

1 được áp dụng cho (-) như là đối số đầu tiên của nó, vì vậy thay vì (list_item - 1), tôi nhận được (1 - list_item). Tôi có thể viết lại nó như thêm một tiêu cực thay vì trừ dương một:

List.map ((+) -1) [1..5];; 
List.map (fun x -> x-1) [1..5];; // this works too 

Tôi đang tìm kiếm một cách biểu cảm hơn để viết nó, một cái gì đó giống như ((-) _ 1), nơi _ biểu thị một placeholder, như trong ngôn ngữ Arc. Điều này sẽ gây ra 1 làm đối số thứ hai cho -, vì vậy trong List.map, nó sẽ đánh giá là list_item - 1. Vì vậy, nếu bạn muốn để lập bản đồ divide by 2 vào danh sách, bạn có thể viết:

List.map ((/) _ 2) [2;4;6] //not real syntax, but would equal [1;2;3] 
List.map (fun x -> x/2) [2;4;6] //real syntax equivalent of the above 

này có thể được thực hiện hay tôi phải sử dụng (fun x -> x/2)? Có vẻ như gần nhất chúng ta có thể nhận được cú pháp giữ chỗ là sử dụng một lambda với một đối số được đặt tên.

Trả lời

11

Bạn có thể viết một hàm lật, một cái gì đó như:

let flip f x y = f y x 

List.map (flip (-) 1) [2;4;6] 

tôi có thể có cú pháp sai, tôi không khủng khiếp thạo F #.

+8

Bạn có thể định nghĩa chức năng lật của bạn (chỉ cần tốt) là 'cho phép lật f x y = f y x' –

+0

Đó là một ứng cử viên tốt cho nội tuyến. –

8

Không có 'phần hoạt động' trong F #, một la Haskell, cũng như các đối số giữ chỗ (rõ ràng là một la Arc). Bạn có thể sử dụng bộ kết hợp 'lật' như được đề xuất trong một câu trả lời khác để đảo ngược thứ tự của các đối số và sau đó áp dụng một phần đối số đầu tiên (hiện tại thứ hai).

Nhưng tôi sẽ chỉ cần sử dụng

fun x -> x/2 

Trừ khi bạn đang chơi mã golf, tôi không nghĩ rằng cố gắng để cạo một vài ký tự tắt ở đây mua bạn bất cứ điều gì.

8

Các -solution flip đề xuất bởi Logan Capaldo cũng có thể được viết bằng một nhà điều hành (ở đây >.):

let (>.) x f = (fun y -> f y x) 
List.map (1 >. (-)) [2;4;6] 

Hoặc nếu bạn thích các toán hạng theo cách khác xung quanh:

let (>.) f x = (fun y -> f y x) 
List.map ((-) >. 1) [2;4;6] 

Sửa : Sử dụng toán tử "trông giống như trình giữ chỗ" (ở đây >-<) giúp bạn rất gần với cú pháp được đề xuất:

List.map ((-) >-< 1) [2;4;6] 

'_' là không may (?) Không a valid operator symbol in F#.

+1

:) Smiley. : (frownie.: p lưỡi.> - một mắt thò ra ... (cau mày với một mắt thò ra. – Juliet