相当于`_1`样式元组镜头快捷方式的数据类?

Tyc*_*cho 2 haskell lenses haskell-lens

根据其文档,Haskell 的lens_1为元组提供了一个镜头。

对于数据记录,还有其他几个功能,例如makeLenses,根据记录的字段名称自动生成镜头。

不幸的是,我正在处理没有命名字段的数据类,这makeLenses对我来说意味着意义。这让我感到奇怪。_1看起来很方便,但正如其文档中暗示的那样,似乎不适用于数据类。是否有同等程度的便利?

> :set -package lens
> import Control.Lens
> (1,2) ^. _1
1
> data Bar = Bar String deriving Show
> bar = Bar "abc"
> bar ^. _1

<interactive>:271:1: error:
    • Non type-variable argument in the constraint: Field1 Bar Bar b b
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall b. Field1 Bar Bar b b => b
Run Code Online (Sandbox Code Playgroud)

添加FlexibleContexts扩展名,我反而面临另一个错误:

bar ^. _1

<interactive>:6:1: error:
    • No instance for (Field1 Bar Bar () ()) arising from a use of ‘it’
    • In the first argument of ‘print’, namely ‘it’
      In a stmt of an interactive GHCi command: print it
Run Code Online (Sandbox Code Playgroud)

Li-*_*Xia 5

Field1 有一个默认的通用实现,所以你可以自己添加一个实例:

{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic)

data Bar = Bar String deriving (Show, Generic)

instance Field1 Bar Bar String String
Run Code Online (Sandbox Code Playgroud)

generic-lens 也提供相同的功能,而不需要样板实例。_1被调用position @1(来自Data.Generics.Product( .Positions))。