2013-07-11 27 views
8

Xin hãy giúp tôi hiểu được định nghĩa sau đây:Haskell Newtype cú pháp

newtype Writer w a = Writer { runWriter :: (a,w) } 

instance (Monoid w) => Monad (Writer w) where 
    return a    = Writer (a,mempty) 
    (Writer (a,w)) >>= f = let (a',w') = runWriter $ f a in Writer (a',w `mappend` w') 

Tại sao runWriter được khai báo là

runWriter :: (a,w) 

khi loại thực tế của nó là:

runWriter :: Writer w a -> (a, w) 

Khi tôi đã thử với ghci Tôi nhận ra điều này phải là một số đối số ngầm định vì loại "a" phải được xác định, nhưng chính xác những gì đang xảy ra ở đây?

Trả lời

8

runWriter là trình truy cập trường bản ghi trên Writer. Nó thực sự gần như tương đương với

runWriter (Writer x) = x 

Haskell chỉ đã ghi để cung cấp cho

  1. cú pháp More tiện lợi từ loại mã này accessor là khá phổ biến
  2. Khả năng cập nhật chức năng
  3. Một vài khác tiện ích mở rộng

ví dụ:

someWriter{runWriter = (new, values)} -- Returns a new Writer. 

Nếu nó giúp, hãy nghĩ về nó như một cái gì đó giống như "getter chức năng" theo nghĩa thô nhất. Điều này có vẻ không quan trọng khủng khiếp với 1 trường, bạn luôn có thể khớp mẫu, nhưng khi bạn có 5 trường, bản ghi + cập nhật chức năng là cực kỳ hữu ích. Xem LYAH để có giải thích sâu hơn.

0

Một cách khác để nhìn vào nó: Bạn có thể tưởng tượng được xác định 2-tuples như vậy (nếu (,) cú pháp đặc biệt là chưa một đặc biệt built-in)

data (,) a b = (,) { fst :: a, snd :: b } 

và sau đó fstsnd sẽ hành xử như bình thường:

fst :: (a,b) -> a 
fst (x,y) = x 

(. newtype như trong ví dụ của bạn hoạt động với nhiều loại chỉ với một lĩnh vực có giá trị với nhiều loại với nhiều lĩnh vực, data là cần thiết.)

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