我一直在研究此article中给出的用于创建镜头的示例。
如本文所述,我创建了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
最佳答案
这是正常现象。 lens
库在很大程度上依赖于多态性,因此单态性限制(这使事物的多态性比实际情况要少)不能很好地与它交互。就您而言,我想您也可以这样编写代码:
meetupLat :: Lens' Meetup Latitude
meetupLat = location._1
如果为绑定(bind)提供显式的多态类型签名,则单态性限制无关紧要。
注意
Lens' Meetup Latitude
是多态的,即使它看起来是单态的。类型变量隐藏在Lens'
类型同义词中。特别是:Lens' Meetup Latitude
是Lens Meetup Meetup Latitude Latitude
的defined。Lens Meetup Meetup Latitude Latitude
是defined作为forall f. Functor f => (Meetup -> f Meetup) -> Latitude -> f Latitude
这就是有关
f
的全部内容。我认为,单态性限制将强制f
的具体实例化,但是您希望将其保持多态性,因为镜头的不同用户将选择不同的f
。例如, view
将选择 Const
,而 set
将选择 Identity
。因此,保持f
多态性以允许镜片使用者进行这些选择是非常重要的。关于haskell - 镜片和单晶性限制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23066099/