2012-01-06 24 views
15

Tôi nghĩ rằng tôi hiểu cách các functors ứng dụng hoạt động trong Haskell và tôi đang sử dụng chúng cho các kiểu dữ liệu cơ bản (Có thể, Hoặc là ...). Tuy nhiên, tôi thấy this question với ví dụ sau:functor ứng dụng nào được sử dụng để chuyển các tham số được chia sẻ?

withPool pool = bracket (takeConn pool) (putConn pool) 

có thể được viết lại bằng phong cách applicative:

withPool = bracket <$> takeConn <*> putConn 

Tôi đã ngạc nhiên khi nó được biên soạn và thực sự nó hoạt động như mong đợi, nhưng ai có thể cho tôi biết đó là applicative Functor được sử dụng cho điều này và nó được định nghĩa như thế nào?

Cập nhật: Tôi nghĩ rằng tôi đã tìm ra cách hoạt động, nhưng tôi không biết nó được xác định ở đâu.

Trả lời

17

Unify f = (a ->) trong chữ ký loại:

fmap :: (b -> c) -> (a -> b) -> (a -> c) 
pure :: b -> (a -> b) 
(<*>) :: (a -> b -> c) -> (a -> b) -> (a -> c) 

Lý do duy nhất tờ khai là cú pháp khác nhau, ((->) a) vs (a ->), là bạn không được phép để mất phần ở cấp loại. Vì vậy, bạn kết thúc với những, sau khi loại đuổi:

instance Functor ((->) a) where 
    fmap = (.) 

instance Applicative ((->) a) where 
    pure = const 
    f <*> g = \x -> f x $ g x 

Tôi khá chắc chắn rằng dụ Functor là trong Data.Functor, và dụ Applicative là trong Control.Applicative. Ví dụ Monad cho ((->) a) là trường hợp duy nhất ở một vị trí lạ, trong Control.Monad.Instances, thay vì Control.Monad. Ít nhất nếu tôi nhớ chính xác.

+9

Đối với giá trị của nó, thực tế là trình đọc, trừ một trình bao bọc 'newtype' -" tham số chia sẻ "ở đây giống với" môi trường "cho' Reader'. Theo cách tương tự, 'Hoặc err' là đơn nguyên lỗi và' (,) w' là người viết. –

+0

@ C.A.McCann Thật đáng để chỉ ra, và tôi đã quên. Cảm ơn bạn đã thêm điều đó. – Carl

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