2016-08-11 22 views
5

Tôi có đoạn mã này đó là nghĩa vụ để tạo ra cái tên ngẫu nhiên:Buộc let để ràng buộc vào một chức năng thay vì một giá trị

let generateName = 
    let rnd = System.Random() 
    let c1 = rnd.Next(65, 90) |> System.Convert.ToChar |> string 
    let c2 = rnd.Next(65, 90) |> System.Convert.ToChar |> string 
    let n = rnd.Next(0, 999) |> string 
    c1 + c2 + n 

này để đánh giá một chuỗi, mà không phải là khá những gì tôi muốn. Thêm một đơn vị-Parameter sửa chữa vấn đề, nhưng bây giờ tôi phải gọi hàm của tôi như một hàm C#:

let myFunc() = 
    "Hello" 

myFunc() 

Đây có phải là làm thế nào tôi phải làm điều đó, hoặc là có một cách thành ngữ hơn?

Trả lời

5

Không, đó là cách F # hoạt động. Mỗi hàm trong F # phải có một tham số (hàm có nhiều tham số được chia thành nhiều hàm với một tham số trả về hàm trung gian) và mọi hàm phải trả về một cái gì đó, ngay cả khi nó là đơn vị.

+1

Không bao giờ nghĩ về nó theo cách này, có ý nghĩa hơn bây giờ! –

5

Đây là cách hoạt động chính xác. Một hàm không có tham số "hữu ích" cần phải có tham số unit để thực sự làm cho nó trở thành một hàm.

Không có gì khác biệt khi tách biệt tên hàm và () bằng khoảng trắng để làm cho nó trông hơi kém hơn một chút so với phương thức y và nhiều hàm-y, nhưng đó hoàn toàn là mỹ phẩm.

6

TL; DR:() trong bối cảnh này có một ý nghĩa hoàn toàn khác so với nó có trong C#, do đó, không định dạng nó theo cách tương tự như trong C# - sử dụng let myFunc() =myFunc() thay vào đó, phản ánh tốt hơn ngữ nghĩa thực tế và sẽ lần lượt làm rõ cách bạn suy nghĩ và hiểu mã.


Trong C#, () nghĩa một tập rỗng của các tham số (đối với định nghĩa chức năng/constructor) hoặc đối số (đối với chức năng/constructor gọi trang web); tức là, nó xác định hoặc gọi hàm nullary. Trong F #, () là một loại chữ unit, giống như cách 42 là một loại chữ int; tức là, nó là một giá trị trong và của chính nó, giống như [] là một giá trị cho một danh sách trống. Sự khác biệt này có rất ít ý nghĩa.

Trong F #, khi bạn xác định một -function let với chỉ () cho các thông số, như trong let myFunc() =, bạn đang thực sự sử dụng cú pháp mô hình khớp để xác định một unary chức năng với một tham số kiểu unit (không chức năng nullary!). Ví dụ cụ thể của mô hình kết hợp như vậy được đưa cho các cấp mà nhiều người không nhận ra rằng đó là mô hình phù hợp ở nơi đầu tiên; nhưng, trên thực tế, việc xác định hàm là let myFunc() = thay vì là let myFunc (_:unit) = cũng giống như có let myFunc [] = thay vì let myFunc (x:'a list) = (và sau đó khẳng định rằng x trống).

Và trong F #, khi bạn gọi một -function let với (), như trong myFunc(), bạn không biểu thị 'không có đối số'; bạn đang thực tế cung cấp một đối số kiểu unit, có giá trị ít được sử dụng thường xuyên đến mức nó có cú pháp ngữ của riêng nó: ().

Để thuyết phục chính mình unit là khác nhau từ 'không có tham số/lập luận', và trên thực tế chỉ là một tham số/lập luận giống như bất kỳ khác, hãy xem xét một thực tế rằng sau đây là hoàn toàn hợp pháp:

let myFunc() (i:int) (_:unit*unit) = i 
let n = myFunc() 42((),()) 
printfn "%d" n 

Như bạn có thể thấy, việc cung cấp điều trị khoảng trắng đặc biệt là unit là ngớ ngẩn vì đó là không phải là đặc biệt. ; -]

summarily, vì nó là bình thường (? Cần thiết) để tách bất kỳ tên tham số/cãi nhau với khoảng trắng, nó là sau đó ngữ để phù hợp và làm tương tự với biểu tượng mẫu/giá trị:

let myFunc() = 
    "Hello" 

myFunc() 
+2

"thành ngữ" có thể là một từ mạnh mẽ. Ví dụ, nguồn FSharp.Core không sử dụng kiểu này. https://github.com/fsharp/fsharp/tree/master/src/fsharp/FSharp.Core. Cá nhân tôi đã nhảy qua lại giữa các kiểu và kết thúc với biến thể không gian. Trong khi 'đơn vị' là một arg, tôi thấy nó có một ý nghĩa đặc biệt -" chạy hàm này ". –

+1

Trong thực tế, tôi đã từng đi xa đến mức bao gồm thêm một '()' trong tất cả các hàm, do đó, với ví dụ 'let f() = rand()' và 'g x() = rand() + x',' f' và 'g 1' có thể được xử lý giống nhau. Tuy nhiên, điều đó không hoạt động tốt khi sử dụng với ví dụ: 'map'; các tham số thêm ném nó ra Sự khác biệt? Tác dụng phụ. Vì vậy, lý tưởng, bất cứ điều gì với các tác dụng phụ, tôi sẽ bổ sung thêm '()' ngay cả khi các tham số khác tồn tại. Đáng buồn thay nó trông khá ngớ ngẩn trong F # vì vậy tôi đã chuyển đến Haskell, nơi nó làm cho ý nghĩa hơn rất nhiều và được phân biệt bởi sự cần thiết. –

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