2014-04-14 13 views
10

Ich habe die Beispiele ausgearbeitet, die in dieser article zum Erstellen von Objektiven gegeben wurden.Objektive und Monomorphie Restriktion

I erstellt Lens wie in dem Artikel erwähnt und die folgende ist mein Code:

{-# 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 

dieser Code jetzt nicht typecheck, wenn ich diese beinhalten:

{-# LANGUAGE NoMonomorphismRestriction #-} 

aber nicht, wo in der Artikel konnte ich herausfinden, dass sie über die Monomorphie-Einschränkung erwähnt haben. Also ist das eine normale Sache oder bin ich etwas falsch machen hier?

Compiler verwendet: GHC 7.6.2

+0

Was ist, wenn Sie es als 'meetupLat :: Lens 'Meetup Latitude definieren; 'meetupLat = location._1'? – bheklilr

+0

@bheklilr Danke, das funktioniert ohne die Erweiterung. Kannst du das als Antwort posten? – Sibi

+0

@bheklilr Fertig. :) – Sibi

Antwort

11

Dies ist eine normale Sache. Die lens-Bibliothek beruht stark auf Polymorphie, so dass die Monomorphie-Einschränkung (die die Dinge weniger polymorph macht als sie sein könnte) nicht so gut mit ihr interagiert. In Ihrem Fall, ich glaube, Sie auch Ihren Code so schreiben könnten:

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

Wenn Sie eine explizite polymorphe Art Signatur für eine Bindung zur Verfügung stellt, wird die Monomorphismus Einschränkung keine Rolle.

Beachten Sie, dass Lens' Meetup Latitude ein polymorpher Typ ist, obwohl es monomorph aussieht. Die Typvariablen sind innerhalb des Lens' Synonyms versteckt. Insbesondere gilt:

Lens' Meetup Latitude ist defined als Lens Meetup Meetup Latitude Latitude.

Und Lens Meetup Meetup Latitude Latitude ist defined als forall f. Functor f => (Meetup -> f Meetup) -> Latitude -> f Latitude

Also das alles über die f ist. Ich denke, die Monomorphismus-Beschränkung würde eine konkrete Instantiierung von f erzwingen, aber Sie wollen es polymorph halten, weil verschiedene Benutzer des Objektivs verschiedene f wählen werden. Zum Beispiel view wird wählen Const und set wird Identity wählen. So ist es wirklich wichtig, die f polymorph zu halten, um den Benutzern der Linse diese Möglichkeiten zu ermöglichen.

4

Sie müssen nur die Art auf die Funktion angeben, anstatt auf seine Definition

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

Ich glaube, dies wegen der komplizierten Art von Lens' hinter der ist Szenen bedeutet, dass, während seine Definition diesen Typ hat, der Compiler immer noch schwer erraten kann, dass meetupLat denselben Typ hat. Vielleicht kann jemand, der eine tiefere Kenntnis der Monomorphismus-Beschränkung hat, besser arbeiten.

Verwandte Themen