8

标准makeLenses实现为以下划线开头的记录的所有字段生成镜头。由于许多原因,我非常不喜欢在我的记录中引入如此尴尬的命名约定的想法。我想要做的只是为记录的所有字段生成镜头,并通过在字段名称后附加一个后缀“L”来命名它们。

有了一个fc-labels库,我所要做的就是

mkLabelsWith (++ "L") [''MyRecord]

但是镜头库的规则集和东西的配置要复杂得多,这并不容易引起人们的注意。所以我要求一个特定的配方来达到同样的效果。

4

2 回答 2

18

shachaf 的回答不适用于改变了模板-haskell 相关 API 的镜头 4.4+。

以下是适用于这些版本的实现:

import Language.Haskell.TH

myMakeLenses :: Name -> DecsQ
myMakeLenses = makeLensesWith $ lensRules
    & lensField .~ \_ _ name -> [TopName (mkName $ nameBase name ++ "L")]

(这是 4.5+,在 4.4 中,lambda 只会\_ name作为参数)

于 2014-10-25T14:05:25.057 回答
15

查看代码,它似乎非常简单。LensRules有一个功能lensField :: String -> Maybe String(要么给出镜头的名称,要么失败)。所以你可以做一个像

myMakeLenses = makeLensesWith $ lensRules
  & lensField .~ (\name -> Just (name ++ "L"))

并使用它代替makeLenses. 当然你可以参数化你的函数在(++ "L").

或者,如果您愿意,也可以内联编写它,例如

makeLensesWith ?? ''Foo $ lensRules
  & lensField .~ (\name -> Just (name ++ "L"))

(请注意,这(??)只是flip按正确顺序传递参数的中缀。在这种情况下,您可以将其视为第二个参数被填充的“洞”。并且(&)只是翻转($)。)

于 2013-06-16T11:10:54.720 回答