2010-05-08 33 views
6

Đây không phải là vấn đề thực tế quan trọng, nhưng tôi muốn xem ví dụ về tacit programming trong F # trong đó chức năng điểm miễn phí của bạn có thể có nhiều đối số (không phải dưới dạng danh sách hoặc bộ) .Cách thức lập trình bằng cách sử dụng F #

Và thứ hai, cách các chức năng như vậy có thể thao tác cấu trúc dữ liệu phức tạp . Tôi đang thử nó trong F # Interactive, nhưng vẫn chưa thành công.

tôi đã cố gắng, ví dụ:

> (fun _ -> (fun _ -> (+))) 333 222 111 555 

Có phải đó là đúng cách?

Và:

> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";; 

val it : string = "cd" 
+3

Bạn nên sử dụng "không có điểm" thay vì "vô nghĩa". Đó là thuật ngữ chuẩn. :) –

Trả lời

4

F # không chứa một số chức năng cơ bản có sẵn trong Haskell (chủ yếu là bởi vì F # lập trình viên thường thích phong cách rõ ràng về lập trình và sử dụng phong cách pointfree chỉ trong các trường hợp rõ ràng nhất , nơi nó không làm tổn thương khả năng đọc).

Tuy nhiên bạn có thể định nghĩa một vài combinators cơ bản như thế này:

// turns curried function into non-curried function and back 
let curry f (a, b) = f a b 
let uncurry f a b = f (a, b) 

// applies the function to the first/second element of a tuple 
let first f (a, b) = (f a, b) 
let second f (a, b) = (a, f b) 

Bây giờ bạn có thể thực hiện các chức năng để thêm độ dài của hai chuỗi bằng combinators như sau:

let addLengths = 
    uncurry (((first String.length) >> (second String.length)) >> (curry (+))) 

này xây dựng hai hàm áp dụng String.length vào phần tử đầu tiên/thứ hai của một bộ dữ liệu, sau đó soạn chúng và sau đó thêm các phần tử của bộ túp bằng cách sử dụng +. Toàn bộ điều được gói trong uncurry, vì vậy bạn có được chức năng loại string -> string -> int.

+0

Tôi đã kiểm tra trong FSI và nó hoạt động! Cảm ơn nhiều; btw, bạn có thể giải thích làm thế nào bạn nhận được cú pháp thành phần chức năng tuple đó? Tôi có nghĩa là '(đầu tiên String.length) >> (thứ hai String.length)' Nó trông hơi khác thường với tôi;) – Bubba88

+0

Đó là đạt được bằng cách sử dụng thành phần chức năng '>>'. Ví dụ 'f >> g' có nghĩa là đối số' x', nó sẽ gọi 'g (f (x))'. Trong trường hợp trên, hàm đầu tiên ('first String.length') chuyển một chuỗi' string * string' thành 'tuple' int * string' và hàm thứ hai ('second String.length') biến thành' int * int' chứa các độ dài. –

+0

Bạn đang thực tế thực hiện các mũi tên cho F #;) Được rồi, tại sao không - Mũi tên đã được phát minh như là một sự kết hợp của các chương trình monads và tacit. – Dario

2

Trong F #, các arity chức năng là cố định, vì vậy bạn sẽ không có khả năng viết cả

(op) 1 2 

(op) 1 2 3 4 

đối với bất kỳ nhà điều hành đưa op. Bạn sẽ cần phải sử dụng một danh sách hoặc cấu trúc dữ liệu khác nếu đó là những gì bạn muốn. Nếu bạn chỉ đang cố tránh các biến được đặt tên, bạn luôn có thể thực hiện "1 + 2 + 3 + 4". Cách thành ngữ nhất để thêm danh sách các số trong F # là List.sum [1;2;3;4], cũng tránh các biến.

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