镜头和单态限制

Sib*_*ibi 10 haskell haskell-lens

我一直在研究本文中给出的用于创建镜头的示例.

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
Run Code Online (Sandbox Code Playgroud)

现在这个代码没有类型检查,除非我包含这个:

{-# LANGUAGE NoMonomorphismRestriction #-}
Run Code Online (Sandbox Code Playgroud)

但在文章中没有任何地方,我可以发现他们已经提到了单态限制.这是正常的事情还是我在这里做错了什么?

编译使用:GHC 7.6.2

Tox*_*ris 11

这是正常的事情.该lens库在很大程度上依赖于多态性,因此单态性限制(使得事物变得不那么多态)与它没有很好的相互作用.在您的情况下,我认为您也可以像这样编写代码:

meetupLat :: Lens' Meetup Latitude
meetupLat = location._1
Run Code Online (Sandbox Code Playgroud)

如果为绑定提供显式多态类型签名,则单态限制无关紧要.

请注意,这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将选择Constset将选择Identity.因此,保持f多态性以允许镜头用户进行这些选择非常重要.