2011-11-29 30 views
74

Ai đó có thể giải thích các ống kính chức năng cho tôi? Đó là một chủ đề khó khăn đáng ngạc nhiên đối với google và tôi đã không thực hiện bất kỳ tiến bộ nào. Tất cả những gì tôi biết là chúng cung cấp chức năng get/set tương tự như trong OO.Ống kính chức năng

+7

Có [giới thiệu tốt về ống kính] (http://www.youtube.com/watch?v=efv0SQNde5Q) bởi Edward Kmett trên YouTube. Các ví dụ ở Scala, nhưng nó không quá khó để làm theo. – hammar

+0

Yup, cố xem những thứ đó, nhưng có đủ thời gian trong khi tôi vẫn tỉnh táo, không dễ như vậy: P – Masse

+2

@Jochen: Các thấu kính được mô tả không thực sự có nhiều điểm chung với các ống kính mà câu hỏi này nói đến. – sclv

Trả lời

56

Một ống kính bao gồm hai chức năng, một getter và setter:

data Lens a b = Lens { getter :: a -> b, setter :: b -> a -> a } 

Ví dụ, chúng ta có thể có ống kính cho các bộ phận đầu tiên và thứ hai của một cặp:

fstLens :: Lens (a, b) a 
fstLens = Lens fst $ \x (a, b) -> (x, b) 

sndLens :: Lens (a, b) b 
sndLens = Lens snd $ \x (a, b) -> (a, x) 

Các thực sự tiện lợi của ống kính là chúng sáng tác:

compose :: Lens b c -> Lens a b -> Lens a c 
compose f g = Lens (getter f . getter g) $ 
        \c a -> setter g (setter f c (getter g a)) a 

Và chúng chuyển đổi thành State chuyển tiếp:

lensGet :: MonadState s m => Lens s a -> m a 
lensGet = gets . getter 

lensSet :: MonadState s m => Lens s b -> b -> m() 
lensSet f = modify . setter f 

lensMod :: MonadState s m => Lens s b -> (b -> b) -> m() 
lensMod f g = modify $ setter f =<< g . getter f 

(+=) :: (MonadState s m, Num b) => Lens s b -> b -> m() 
f += x = lensMod f (+ x) 
+0

Ví dụ soạn thư của bạn đã không đánh máy. GHC infers; Lens a -> Lens a -> Lens a – Masse

+0

Masse: Tôi vô tình lật 'f' và' g'. – Apocalisp

+0

Nó vẫn không đánh dấu vào a-> c. Nó xâm nhập vào soạn thảo :: Lens a b -> Lens a -> Lens a b – Masse

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