2014-04-14 7 views
10

Pracowałem nad przykładami podanymi w tym dokumencie: article do tworzenia soczewek.Ograniczenia dotyczące soczewek i monomorfizmów

stworzyłem Lens jak podano w artykule i po to mój kod:

{-# LANGUAGE TemplateHaskell #-} 
import Control.Lens 

type Degrees = Double 
type Latitude = Degrees 
type Longitude = Degrees 

data Meetup = Meetup { _name :: String, _location :: (Latitude, Longitude) } 
makeLenses ''Meetup 

meetupLat = location._1 :: Lens' Meetup Latitude 

Teraz ten kod nie typecheck chyba że to w ten sposób:

{-# LANGUAGE NoMonomorphismRestriction #-} 

Ale nie ma gdzie w Artykuł, mógłbym się dowiedzieć, że wspomnieli o o ograniczeniu monomorfizmu. Czy to normalne, czy też robię coś nie tak?

Compiler używane: GHC 7.6.2

+0

Co jeśli zdefiniujesz go jako 'MeetingupLat :: Lens 'Meetup Latitude'; 'meetupLat = location._1'? – bheklilr

+0

@bheklilr Dzięki, że działa bez rozszerzenia. Czy możesz to opublikować jako odpowiedź. – Sibi

+0

@bheklilr Zrobione. :) – Sibi

Odpowiedz

11

Jest to normalne. Biblioteka lens opiera się w dużej mierze na polimorfizmie, więc ograniczenie monomorfizmu (które sprawia, że ​​rzeczy są mniej polimorficzne, niż mogłyby być) nie współdziała z nim tak dobrze. W twoim przypadku, myślę, że można także napisać kod tak:

meetupLat :: Lens' Meetup Latitude 
meetupLat = location._1 

Jeśli podasz wyraźny polimorficzny typu podpis wiążącą, ograniczenie monomorfizm nie ma znaczenia.

Należy pamiętać, że to typ polimorficzny , nawet jeśli wygląda monomorficznie. Zmienne typu są ukryte wewnątrz synonimu typu Lens'. W szczególności:

Lens' Meetup Latitude jest defined jako Lens Meetup Meetup Latitude Latitude.

I Lens Meetup Meetup Latitude Latitude jest defined jak forall f. Functor f => (Meetup -> f Meetup) -> Latitude -> f Latitude

Więc to wszystko o f. Myślę, że ograniczenie monomorfizmu wymusiłoby konkretną instancję f, ale chcesz zachować ją polimorficzną, ponieważ różni użytkownicy obiektywu będą wybierać inny f. Na przykład view wybierze Const, a set wybierze Identity. Dlatego tak ważne jest zachowanie polimorficzności f, aby pozwolić użytkownikom obiektywu na takie wybory.

4

Trzeba tylko określić typ na funkcję, a nie na jej definicji

meetupLat :: Lens' Meetup Latitude 
meetupLat = latitude._1 

Wierzę, że to ze względu na skomplikowany typ Lens' tył Sceny oznaczają, że chociaż jego definicja ma ten typ, kompilator wciąż ma problemy z odgadnięciem, że meetupLat ma ten sam typ. Może ktoś, kto ma głębszą wiedzę na temat ograniczenia monomorfizmu, może rozwinąć się lepiej.