我一直在研究此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 LatitudeLens Meetup Meetup Latitude Latitudedefined
Lens Meetup Meetup Latitude Latitudedefined作为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/

10-11 04:22