Làm thế nào có thể Monad liên quan đến các loại tùy chọn?


8

Tôi đang thực hiện một bài thuyết trình về F # và đang thảo luận về loại Tùy chọn khi ai đó trong khán giả hỏi tôi rằng loại Tùy chọn có phải là triển khai của F # có thể là đơn nguyên không. Tôi biết đó không phải là trường hợp nhưng tôi đã muốn hỏi làm thế nào hai khái niệm này có liên quan với nhau. Ý tôi là dường như với tôi rằng một loại tùy chọn có thể là kết quả của hoạt động của một đơn nguyên có thể nhưng tôi thậm chí không chắc chắn về điều đó.

Ai đó sẽ làm sáng tỏ mối quan hệ giữa đơn nguyên có thể và loại tùy chọn trong các ngôn ngữ chức năng hỗ trợ nó?


4
Chỉ tò mò, nhưng làm sao bạn biết that's not the case? Họ trông rất giống tôi.

Đó là lý do tại sao tôi hỏi.
Onorio Catenacci

Câu trả lời:


8

Đọc tài liệu về loại của F # Option, có vẻ như nó hoạt động khá giống với Maybeloại trong Haskell, trong đó nó có thể mô hình hóa 'không có gì' ( Nonetrong F #, Nothingtrong Haskell) hoặc giá trị của loại đối số của nó ( Sometrong F #, Justtrong Haskell).

Tuy nhiên, trong Haskell Maybecũng là một đơn nguyên và hệ thống ống nước sao cho nó tính toán Maybecác giá trị, trả về sớm Nothingnếu có bất kỳ biến nào trong phép tính Nothing. Được sử dụng theo cách này, Maybelà một trình xử lý lỗi đơn giản (hay đúng hơn là thiết bị bỏ qua lỗi) và thực tế rằng nó là một đơn vị cho phép di chuyển nồi hơi ra khỏi đường đi. Nhìn vào bài viết wikipedia này cho một ví dụ súc tích tốt đẹp. Tôi không nghĩ Optionhỗ trợ loại sử dụng đơn nguyên này (thực tế, tôi tự hỏi liệu có bất kỳ khái niệm rõ ràng nào về một đơn nguyên trong F # không). Nếu bạn muốn hành vi này trong .NET, tôi đoán bạn sẽ sử dụng Option.Valuecho tất cả các đối số của mình và bao bọc toàn bộ phép tính trong một lần thử / bắt NullReferenceException.

Vì vậy, trong khi Optiontương tự như Maybe loại , nó không tương đương với Maybe đơn nguyên .


Cảm ơn lời giải thích sáng suốt. Thành thật mà nói tôi luôn coi họ không giống nhau (một kiểu người khác là một đơn nguyên) nhưng tôi không hoàn toàn rõ ràng về cách người này liên quan đến người khác.
Onorio Catenacci

BTW - có một loại khái niệm đơn nguyên trong F #; nó được gọi là biểu thức tính toán.
Onorio Catenacci

@OnorioCatenacci: À, được rồi. Tôi chưa có nhiều tiếp xúc với F #, vì vậy xin lỗi. Dù sao, trong Haskell, các đơn nguyên các loại, cụ thể hơn, các loại của kiểu chữ Monad. Maybelà một kiểu dữ liệu cũ đơn giản, nhưng nó cũng xảy ra để thực hiện Monadđể cung cấp hành vi 'đặc biệt' này.
tdammers

2
Nói tóm lại: Tôi hoàn toàn không đồng ý rằng chúng không tương đương. cấu trúc ngôn ngữ như các lớp loại hoặc đa hình không thay đổi một loại thuộc tính và cấu trúc toán học cơ bản.
sara

2
'S Lựa chọn của F # mapbindchức năng cư xử y hệt của Haskell lẽ là fmapbindchức năng. Cả hai đều là đơn nguyên và có hành vi đơn nguyên tương đương. Haskell chỉ có một kiểu chữ Monadcho phép bạn thao tác các đơn nguyên, trong khi ở F # chúng giống như một "mẫu thiết kế" trừu tượng.
Jack

9

Vâng, chúng tương đương theo nghĩa là Optionloại cùng với Option.bindvà loại xây dựng Sometạo thành một đơn nguyên.

Trong khi các đơn nguyên (như trong kiểu chữ Monad) là một phần trung tâm của bản sắc Haskells, từ quan điểm khái niệm, chúng là một cấu trúc không thể biết ngôn ngữ. Một mẫu thiết kế nếu bạn thích. Nếu bạn có một loại, và bạn có một ràng buộc và hàm trả về với các chữ ký cụ thể tuân theo một bộ luật cụ thể - bạn có một đơn nguyên - bất kể ngôn ngữ bạn sử dụng.

Các biểu thức tính toán F # chỉ cung cấp một đường cú pháp có thể lập trình cho các đơn nguyên, tương tự như ký hiệu trong Haskell. Mặc dù không có trình Optionxây dựng biểu thức tính toán nào được cung cấp ngoài hộp, bạn có thể dễ dàng xác định một trình tạo xương trần như thế này:

type OptionBuilder () = 
    member this.Bind(m, f) = Option.bind f m
    member this.Return(a) = Some a 

let option = OptionBuilder ()  

Và sử dụng nó như thế này:

let c = 
    option {
        let! a = Some 4
        let! b = None
        return a + b
    }

tương đương với đường như thế này:

let c =
    (Some 4) 
    |> Option.bind (fun a ->
        None 
        |> Option.bind (fun b ->
             Some (a + b)))

Lưu ý cách các thành viên của trình xây dựng phản chiếu kiểu chữ Monadvà cách bạn có thể viết đơn âm - ngay cả khi bị sai - mã mà không có trình tạo.


3

Chúng tương đương nhau và cả hai đều là đơn nguyên. Sự khác biệt là một đơn nguyên có nghĩa là một cái gì đó trong Haskell - có một kiểu chữ rõ ràng Monadvà "ký hiệu" có thể được sử dụng để loại bỏ rất nhiều bản tóm tắt khi viết mã đơn âm. Trong F #, ký hiệu của trình xây dựng let!do!có thể được sử dụng để loại bỏ các biểu đồ tương tự, nhưng không có khái niệm rõ ràng về loại "là một đơn nguyên". Hệ thống loại của Haskell bao gồm các kiểu chữ (trong đó loại chung Monad) và loại có loại cao hơn (trong đó là một cá nhân Monad), cho phép viết mã hoạt động cho tất cả các đơn nguyên. Hệ thống loại của F # không có các tính năng này.

Vì vậy, có, F # Optionvà Haskell Maybelà giống hệt nhau và cả hai đơn nguyên. Chỉ là Haskell cung cấp cho bạn nhiều máy móc hơn để làm việc với các đơn nguyên so với F #.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.