我正在尝试使用默认值创建记录,并避免在制作记录时使用下划线。我目前正在使用:
data SectionedItems s i = SectionedItems{
_section :: Maybe s,
_items :: [i],
_subsections :: [SectionedItems s i]
}
makeLenses ''SectionedItems
sectionedItems = SectionedItems{
_section = Nothing,
_items = [],
_subsections = []
}
-- Create Instance of SectionedItems
sectionedItems
& section .~ Just x
是否有更短或更清晰的方法来制作具有默认值且没有下划线的记录?
答案 0 :(得分:2)
有一个名为data-default的方便包,它定义了一个类型Default
,它公开了一个函数def :: a
- 一个默认值。此外,虽然我似乎无法找到任何文档,但您可以自动派生它(使用正确的标志和导入的东西)。当然,如果您的默认值必须不同,您可以自己声明实例。
然后,您可以通过以下方式缓解示例中的一些痛苦:
{-# LANGUAGE DeriveGeneric, DeriveAnyClass, TemplateHaskell #-}
import Data.Default
import GHC.Generics
import Control.Lens
data SectionedItems s i = SectionedItems{
_section :: Maybe s,
_items :: [i],
_subsections :: [SectionedItems s i]
} deriving (Generic,Default)
makeLenses ''SectionedItems
-- Create a SectionedItems - this could have whatever type you want
def & section .~ Just 3 :: SectionedItems Int [String]
(尽量不要使用'实例'就像你在OOP中那样,因为Haskell的含义非常不同)。
然而,这并没有取消Lens
中的下划线。我不确定你可以为此做些什么。最重要的是,makeLenses''
函数生成的函数不能与Haskell在创建记录时为您生成的函数进行名称冲突。通过查看Control.Lens.TH你可以看到你可以调节镜头名称是你想要的,但底线你将不得不采用一种惯例 - 记录存取器的下划线和镜头没有下划线是一个好的惯例如任何。
如果要显式定义默认值,请创建Default
的实例:
instance Default (SectionedItems s i) where
def = SectionedItems { _section = Nothing, _items = [], _subsections = [] }