Phê bình về đơn vị IO được xem là một đơn vị nhà nước hoạt động trên thế giới


46

Các IOđơn nguyên trong Haskell thường được giải thích là một đơn vị nhà nước trong đó nhà nước là thế giới. Vì vậy, một giá trị của loại IO ađơn nguyên được xem như một cái gì đó như thế worldState -> (a, worldState).

Cách đây một thời gian, tôi đã đọc một bài viết (hoặc một bài đăng danh sách blog / thư) đã chỉ trích quan điểm này và đưa ra một số lý do tại sao nó không đúng. Nhưng tôi không thể nhớ cả bài báo lẫn lý do. Có ai biết không?

Chỉnh sửa: Bài viết dường như bị mất, vì vậy hãy bắt đầu thu thập các đối số khác nhau ở đây. Tôi đang bắt đầu một tiền thưởng để làm cho mọi thứ thú vị hơn.

Chỉnh sửa: Bài báo tôi đang tìm kiếm là Giải quyết đội hình vụng về: đầu vào / đầu ra đơn điệu, đồng thời, ngoại lệ và các cuộc gọi bằng tiếng nước ngoài trong Haskell của Simon Peyton Jones. (Cảm ơn câu trả lời của TacTics.)



@JoachimSauer Cảm ơn, đây cũng là một bài viết thú vị, nhưng nó không phải là bài tôi đang tìm. Đó là một trong những tập trung vào mô hình của thế giới.
Petr Pudlák

Ngoài đỉnh đầu của tôi, các ý kiến ở đây là một khởi đầu tốt
Adam

1
"Thế giới" nghĩa là gì trong bối cảnh này? Tôi đoán nó không có nghĩa là "Trái đất." Đây có phải là một loại phạm vi toàn cầu? Các tác giả đã viết này là bán mình ngắn. Nếu anh ta muốn đồng thời nhầm lẫn và đè bẹp bản ngã của độc giả, anh ta nên gọi nó là "Nhà nước là vũ trụ" hoặc "Nhà nước của Chúa". Thế giới. Pah! Những người trẻ tuổi không khao khát đủ cao trong những ngày này!
GlenPeterson

Câu trả lời:


33

Vấn đề IO a = worldState -> (a, worldState)là nếu điều này là đúng thì chúng ta có thể chứng minh điều đó forever (putStrLn "Hello") :: IO aundefined :: IO abằng nhau. Dưới đây là bằng chứng lịch sự của dolio (2010, irc):

forever m
 =
m >> forever m
 =
fix (\r -> m >> r)
 = {definition of >> for worldState -> (a, worldState)}
fix (\r -> \w -> r (snd $ m w))

Bổ đề: (\r w -> r (snd $ m w)) ⊥ = ⊥

(\r w -> r (snd $ m w)) ⊥
  =
\w -> ⊥ (snd $ m w))
  =
⊥ . snd . m
  =
⊥

vì thế forever m = fix (\r -> \w -> r (snd $ m w)) = ⊥

Đặc biệt forever (putStrLn "Hello") = ⊥và do đó forever (putStrLn "Hello")undefinedlà các chương trình tương đương. Tuy nhiên, rõ ràng chúng không được coi là chương trình tương đương, trên lý thuyết hoặc trong thực tế.

Lưu ý rằng mô hình này là sai ngay cả khi không gọi đồng thời.


7
Có ai ngạc nhiên khi một chương trình sắp hết hạn tương đương với undefinedngữ nghĩa thuần túy của Haskell không? Các khác nhau được cho là không thể phân biệt trong ngữ nghĩa thuần túy của Haskell! Nhưng khi chúng tôi suy nghĩ vận hành về các chương trình của mình, chúng tôi cũng muốn phân biệt các loại khác nhau, ngay cả khi IOkhông liên quan; Tôi quan tâm liệu chương trình của tôi có đưa ra một ngoại lệ hay đi vào một vòng lặp vô hạn hay không, ngay cả khi bạn có thể chứng minh rằng những điều đó bằng nhau bằng cách chứng minh rằng cả hai đều. Đó thực sự không phải là một mâu thuẫn.
Ben

3
Các ký hiệu của và [0,1 ..] là khác biệt mặc dù cả hai đều "không kết thúc". Sự khác biệt là biểu thị các tính toán không kết thúc không sản xuất, trong khi [0,1 ..] là không kết thúc nhưng hiệu quả. Chúng tôi hy vọng (mãi mãi (putStrLn "Xin chào")) sẽ có một dấu hiệu không kết thúc nhưng hiệu quả tương tự.
Russell O'Connor

1
Nhưng chắc chắn forever (putStrLn "Hello")là không thích [0,1..]. Bằng chứng của bạn không đặc biệt worldState, do đó, nó cũng được áp dụng cho đơn nguyên tiểu bang thông thường. Vì vậy, forever (someModificationWith "Hello")nó cũng tương đương với. Tôi hoàn toàn không ngạc nhiên với kết quả đó; nó không hiệu quả trong ngữ nghĩa học biểu thị, và những gì máy tính đang hoạt động trong khi chúng ta chờ đợi mãi mãi là không liên quan. Điều tương tự cho forever (putStrLn "Hello"); nó không không nên tạo ra một trạng thái thế giới mới, bằng cách nào đó chúng ta có thể tiêu thụ một cách lười biếng.
Ben

Các ngôn ngữ lập trình như Mercury và Clean có sử dụng trạng thái chuyển giao trạng thái rõ ràng để cung cấp mô hình khai báo cho IO về cơ bản là sai không?
Ben

@Ben bạn đang đề cập đến việc thế giới đi qua hoạt động như thế nào với sự tương tranh? Bạn đã thấy mã Rosetta cho đồng thời của Sao Thủy chưa? Tôi đã tự hỏi điều đó có nghĩa là gì về mặt ngữ nghĩa.
CMCDragonkai

12

Đây là một câu trả lời tầm thường: bất kỳ thay đổi nào đối với trạng thái của đơn nguyên bang là do bất kỳ hành động nào được thực hiện trong đơn nguyên. Nếu thực sự lời giải thích của World WorldState -> (a, WorldState) yêu cầu cùng một thuộc tính, với WorldState là một giá trị thuần túy mà chỉ có đơn vị IO thay đổi, thì đó là sai. Thời gian thay đổi, nội dung của tệp, trạng thái xử lý, v.v. có thể thay đổi độc lập với những gì xảy ra trong đơn vị IO. Đó là quan điểm của đơn vị IO. Thực tế là GHC vượt qua một giá trị RealWorld (hoặc w / e nó) bên dưới là để đảm bảo mọi thứ được chạy theo thứ tự, theo như tôi biết, nếu điều đó (có thể chỉ là một cái gì đó để đưa vào giá trị ST).


8
Đó thực sự không phải là một vấn đề. bạn có thể mô hình hóa hoạt động liên kết như thực hiện sửa đổi trạng thái thế giới xuất phát từ một số quy tắc lưu trữ cố định nhưng không thể biết được.
sclv

1
@sclv: có, nhưng cửa hàng quy tắc cố định nhưng không thể biết này là yếu tố khác biệt khiến IO không phải là đơn vị nhà nước, sự không nhất quán này không được tìm thấy trong đơn nguyên tiểu bang
Jimmy Hoffa

Một đối số mà tôi đã nghe chống lại trạng thái WorldState có liên quan đến sự tương tranh, mặc dù tôi không thể nhớ chính xác đối số. Nhưng ngay cả khi vẫn còn, tôi đưa ra giả thuyết rằng WorldState cũng có thể mã hóa tương lai vào nó, vì vậy tôi vẫn không thực sự thấy vấn đề. Tất nhiên, tôi cho rằng tôi đang thiếu một cái gì đó.
Thomas Eding

@JimmyHoffa: Mặc dù vậy, bạn có thể mang theo cửa hàng quy tắc ở trạng thái.
sclv

1
@JimmyHoffa: đây là mục đích của sự trừu tượng. Ngoài ra, để theo dõi nhận xét ban đầu của tôi, Clean mô hình IO là thế giới rõ ràng và vui vẻ, sử dụng các loại duy nhất để đảm bảo rằng bạn không lừa dối và "nhân đôi" thế giới. Đây là một cách để thực thi sự trừu tượng.
sclv

12

Tôi đã viết một bài đăng trên blog về chủ đề làm thế nào để mô hình hóa IO như một hình thức coroutine không đối xứng giao tiếp với hệ thống thời gian chạy cho ngôn ngữ của bạn. (Nó được thừa nhận là phần thứ ba của một loạt)

http://comonad.com/reader/2011/free-monads-for-less-3/

Bài đăng đó bao gồm một chút lý do tại sao thật khó xử khi lý do về ngữ nghĩa của 'thế giới'.


+1 - đặc biệt thú vị, vì từ lâu tôi đã lên kế hoạch triển khai IO của ngôn ngữ mà tôi đang thiết kế theo cách tương tự như thế này! :)
Jules

8

Xem Xử lý đội hình vụng về .

Lý do lớn là các mô hình trạng thái RealWorld của đơn vị IO không hoạt động tốt với sự tương tranh. SPJ trong sự ủng hộ cổ điển dễ đọc này bằng cách sử dụng một ngữ nghĩa hoạt động để hiểu nó.


Tôi tin rằng đây là bài viết gốc mà tôi đang tìm kiếm, chủ yếu là phần 3.1. Nếu bạn đã đăng nó trước khi tôi chỉnh sửa câu hỏi, tôi đã chấp nhận câu trả lời của bạn, nhưng bây giờ tôi nghĩ sẽ công bằng hơn khi chờ đến cuối, để xem tất cả các ý tưởng mà người khác sẽ đăng.
Petr Pudlák

5

Khiếu nại chính về các mô hình nhà nước RealWorld là, như TacTics nói, truyền qua thế giới không nhất thiết phải hoạt động đồng thời. Nhưng Wouter Swierstra và Thorsten Altenkirch đã chỉ ra cách lấy lý do đồng thời là hiệu ứng "xuyên thế giới", với một chuỗi các chủ đề xen kẽ cố định nhưng tùy tiện trong bài báo "Beauty in the Beast: A Functional Sapes for the Aw Aw Squad": http : //www.staff.science.uu.nl/~swier004/Publications/BeautyInTheBeast.pdf

Mã tương ứng với mã này là trên Hackage là IOSpec: http://hackage.haskell.org/package/IOSpec

Tôi nghĩ rằng luận án của Wouter đi sâu vào chi tiết hơn: http://www.staff.science.uu.nl/~swier004/Publications/Tribution.pdf

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.