10

私は、レンズを作成するために、この記事に記載されている例に取り組んできました。

記事に記載されているように作成Lensしました。以下が私のコードです。

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

これを含めない限り、このコードは型チェックしません。

{-# LANGUAGE NoMonomorphismRestriction #-}

しかし、記事のどこにも、彼らが単型性の制限について言及していることを知ることができませんでした。これは正常なことですか、それともここで何か間違ったことをしていますか?

使用コンパイラ: GHC 7.6.2

4

2 に答える 2

11

これは正常なことです。ライブラリはlensポリモーフィズムに大きく依存しているため、モノモーフィズムの制限 (可能な限りポリモーフィックではないものにする) は、それとうまく相互作用しません。あなたの場合、次のようにコードを書くこともできると思います:

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

バインディングに明示的なポリモーフィック型シグネチャを提供する場合、モノモーフィズムの制限は問題になりません。

はモノモーフィックに見えますLens' Meetup Latitudeが、ポリモーフィック型であることに注意してください。Lens'型変数は、型シノニム内に隠されています。特に:

Lens' Meetup Latitudeとして定義さLens Meetup Meetup Latitude Latitudeます。

そして、次のようLens Meetup Meetup Latitude Latitude定義されますforall f. Functor f => (Meetup -> f Meetup) -> Latitude -> f Latitude

したがって、これはすべてについてfです。モノモーフィズムの制限により の具体的なインスタンス化が強制されると思いますfが、レンズのさまざまなユーザーが異なる を選択するため、多態性を維持したいと考えていますf。たとえば、viewを選択Constし、setを選択しますIdentityfしたがって、レンズのユーザーがこれらの選択を行えるように、多態性を維持することが非常に重要です。

于 2014-04-14T17:35:46.223 に答える
4

定義ではなく、関数で型を指定するだけです

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

これは、複雑な型がLens'舞台裏で定義されているため、その定義がその型を持っているにもかかわらず、コンパイラがmeetupLat同じ型を持っていると推測するのにまだ苦労しているためだと思います。モノモーフィズムの制限についてより深い知識を持っている人は、より詳しく説明できるかもしれません。

于 2014-04-14T17:15:38.880 に答える