2016-07-21 13 views
6

Nhìn vào IO mã này:Luật Monoid thứ ba và IO?

Prelude> let e = return() :: IO() 
Prelude> e `mappend` e 
Prelude> let y = e `mappend` e 
Prelude> :t y 
y :: IO() 

EDIT Rõ ràng, như tôi hiểu, IO có một trường hợp Monoid.

Tuy nhiên, không nên đánh giá sau đây để true, để tuân thủ luật thứ ba Monoid?

Prelude> e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e 

<interactive>:14:1: error: 
    * No instance for (Eq (IO())) arising from a use of `==' 
    * In the expression: 
     e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e 
     In an equation for `it': 
      it = e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e 

Trả lời

11

The third monoid law khẳng định rằng e <> (e <> e) = (e <> e) <> e (để sử dụng các nhà điều hành ghi-to-type dễ dàng hơn cho mappend), không rằng e <> (e <> e) == (e <> e) <> e (chú ý = vs ==).

Nó thể hiện một sự tương đương - thực sự, thể hiện rằng mappend nên kết hợp - không đòi hỏi tất cả Monoid s cũng phải thể hiện của các Eq typeclass, nơi == đến từ đâu.

Một cách khác để nói điều này: nó thể hiện ý tưởng cấp cao về hành vi của hàm mappend, không hiển thị mã Haskell hợp lệ cần đánh giá cho bất kỳ điều gì cụ thể.

Một số loại là Monoid s - chẳng hạn như [()], ví dụ - cũng có trường hợp Eq. Nhưng một số (ví dụ như trường hợp IO() ở đây) không, và điều đó không sao.

Sidenote: Nó không thực sự có ý nghĩa để cung cấp cho IO một thể hiện Eq, bởi vì đó là đêm về không thể xác định nếu một số IO() tương đương với IO() khác. Có phải putStrLn "3" "bằng" tới print 3 không? Cả hai đều có tác dụng quan sát giống nhau, nhưng làm thế nào trên trái đất thời gian chạy có thể xác định rằng trong trường hợp chung? Và bạn không thể nói "chúng tương đương nếu chúng tạo ra cùng một giá trị", bởi vì kiểu trả về của == sẽ phải là IO Bool và đó không phải là chữ ký phù hợp cho Eq. Vì vậy, chúng tôi không cung cấp cho IO một phiên bản Eq và điều đó là tốt - tôi không thể đưa ra ví dụ hợp lý về thời điểm một ví dụ như vậy sẽ hữu ích.

Cũng lưu ý rằng "IO" không có phiên bản Monoid (dù sao thì đó là loại sai). mappend mà bạn đang sử dụng xuất phát từ cá thể cho Monoid a => Monoid (IO a) — tức là, công thức nấu ăn IO để sản xuất các loại mà chính chúng là Monoid s. IO Ví dụ Monoid chỉ là "lưng heo" trên phiên bản Monoid cơ bản.

+5

Ví dụ 'Eq (IO a)' hợp lệ, trực quan hợp lệ sẽ rất hữu ích nếu bạn có thể viết một. Nhưng Alan Turing sẽ ngồi trong ngôi mộ của mình và cho bạn một lưỡi lashing nếu bạn cố gắng. – dfeuer

+1

@dfeuer Tôi không thấy sự cố. Xét cho cùng, chúng ta có một cá thể 'Eq [a]'. –

+0

@ReinHenrichs, bạn có một điểm! – dfeuer

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