2009-12-14 14 views
8

Tôi muốn hiểu đó là sự khác biệt giữa hai khái niệm lập trình này. Việc đầu tiên đại diện cho sự vắng mặt của kiểu dữ liệu và sau này loại tồn tại nhưng không có thông tin. Ngoài ra, tôi nhận ra rằng Đơn vị đến từ nền tảng lý thuyết lập trình chức năng nhưng tôi vẫn không thể hiểu khả năng sử dụng của đơn vị nguyên thủy (ví dụ: trong chương trình F #).Void trong constrast với Đơn vị

Trả lời

11

Loại đơn vị chỉ làm mọi thứ đều đặn hơn. Ở một mức độ nào đó, bạn có thể nghĩ về mọi hàm trong F # khi lấy một tham số đơn và trả về một kết quả duy nhất. Các hàm không cần bất kỳ tham số nào thực sự lấy "đơn vị" làm tham số và các hàm không trả về bất kỳ kết quả nào trả về "đơn vị". Điều này có nhiều lợi thế; cho một, hãy xem xét trong C# bạn cần cả một loạt các đại biểu "Func" để đại diện cho các hàm của các số khác nhau trả về giá trị, cũng như một loạt các đại biểu "Action" không trả về giá trị (vì ví dụ: Func<int,void> không hợp pháp - void không thể được sử dụng theo cách đó, vì nó không hoàn toàn là một loại 'thực').

Xem thêm F# function types: fun with tuples and currying

+0

Cũng được giải thích +1 – Dario

+0

Và() chỉ là kết thúc hợp lý của các bộ n-ary, một bộ phần tử 0 phần tử! – Dario

+0

Cảm ơn bạn! Đã đánh dấu. –

8

Trong lập trình hàm, chúng ta thường nói về việc ánh xạ đầu vào cho đầu ra. Điều này có nghĩa là lập bản đồ một đối số cho (các) giá trị trả về của nó. Nhưng nếu một cái gì đó sẽ là một hàm trong ý nghĩa toán học/thể loại lý thuyết, nó phải trả lại một cái gì đó. Giá trị void biểu thị rằng hàm trả về không có gì, điều này là vô nghĩa trong các thuật ngữ này.

unit là câu trả lời chức năng cho void. Về cơ bản, đó là loại chỉ có một giá trị, (). Nó có một số cách sử dụng, nhưng đây là một cách sử dụng đơn giản. Hãy nói rằng bạn có một cái gì đó như thế này trong một ngôn ngữ mệnh lệnh truyền thống hơn:

public static <T, U> List<U> map(List<T> in, Function<T, U> func) { 
    List<U> out = new ArrayList<U>(in.size()); 
    for (T t : in) { 
    out.add(func.apply(t)); 
    } 
    return out; 
} 

này áp dụng một chức năng cụ func để mọi phần tử trong danh sách, tạo ra một danh sách mới của loại đầu ra func 's. Nhưng điều gì sẽ xảy ra nếu bạn vượt qua trong một hàm chỉ in các đối số của nó? Nó sẽ không có loại đầu ra, vì vậy bạn có thể đặt gì cho U?

Trong một số ngôn ngữ, việc truyền chức năng như vậy sẽ phá vỡ mã này (như trong C#, nơi bạn không thể chỉ định void cho loại chung). Bạn sẽ phải sử dụng các giải pháp thay thế như có một số Action<T>, điều này có thể gây khó khăn.

Đây là nơi mà các khái niệm về unit rất hữu ích: một loại, nhưng người ta chỉ có thể đưa vào một giá trị duy nhất. Điều đó đơn giản hóa rất nhiều thứ như chuỗi và thành phần, và làm giảm đáng kể số lượng các trường hợp đặc biệt mà bạn phải lo lắng.

+0

+1 cho câu trả lời này nữa. Đoạn mã của bạn khá kỹ lưỡng. Cám ơn! –