gpt4 book ai didi

haskell - Haskell中的记录有替代品吗?

转载 作者:行者123 更新时间:2023-12-04 05:24:16 25 4
gpt4 key购买 nike

我正在寻找一种更好的替代标准记录的方法,标准记录只是在元组上自动生成的访问器函数。问题是命名问题,其中字段名称相同的记录获得相同的访问器函数。

最佳答案

我正在使用 lens使用 makeFields TH 函数。这让我可以做这样的事情:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens

data Person = Person { _personFirstName :: String
, _personLastName :: String
, _personEmail :: String }

data Corp = Corp { _corpName :: String
, _corpEmail :: String }

makeFields ''Person
makeFields ''Corp

main =
let myGuy = Person "Test" "Guy" "email@account.com"
myCorp = Corp "ABC" "sales@abc.com" in
putStrLn $ "personal email: " ++ (myGuy^.email) ++
"corp email: " ++ (myCorp^.email)

这里发生的是 makeFields 函数创建了类型类 HasName 和 HasEmail ,它们只有一个成员(姓名或电子邮件)。它还为这些类型创建实例。 MultiParamTypeClasses 和Functional Dependencies 使得为不同的数据类型“重载”这些成员成为可能。

按照惯例,makeFields 将对以下划线开头的每个记录构造函数执行此操作,并且它将为字段选择的名称是构造函数名称以第一个大写字母开头的余额。所以 _corpEmail 创建了一个“email”字段。

现在这些“场”都是镜头,有很多 functions你可以和他们一起申请。要简单地从记录中获取值,您可以使用“查看”功能,例如:
view email myGuy
该函数有一个逆函数,称为 (^.),它将记录作为第一个参数,将镜头作为第二个参数。我个人在很多情况下更喜欢这种风格,但有时我仍然使用 View ,特别是在无点风格中。

Lens 比这个功能要大很多——我个人觉得这个功能很有吸引力,但它为您做的最重要的事情是让您能够组合这些镜头以在数据结构中进行深度更新。组合就像任何其他函数一样简单地使用 (.) 运算符;所以如果我们想象我的例子有一个 _corpPresident :: Person场,我可以这样做:
 putStrLn $ myCorp^.president.email 

或 - 更改此嵌套值:
let newCorp = set president.email "changedemail@address.com" myCorp 

或同样的事情(更多的运算符(operator)疯狂):
let newCorp = myCorp & president.email .~ "changedemail@address.com"

还有更多,我自己几乎没有触及表面。 hackage 文档很好,但我认为最好的入门方法是使用 Github 自述文件中的现场指南 repository .

关于haskell - Haskell中的记录有替代品吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20912217/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com