gpt4 book ai didi

haskell - 用于获取或设置由运行时参数确定的记录字段的镜头

转载 作者:行者123 更新时间:2023-12-02 21:05:23 25 4
gpt4 key购买 nike

我有这些类型(以及更多):

data Player = PlayerOne | PlayerTwo deriving (Eq, Show, Read, Enum, Bounded)

data Point = Love | Fifteen | Thirty deriving (Eq, Show, Read, Enum, Bounded)

data PointsData =
PointsData { pointsToPlayerOne :: Point, pointsToPlayerTwo :: Point }
deriving (Eq, Show, Read)

我正在做Tennis kata ,作为实现的一部分,我想使用一些函数,使我能够为任意玩家获取或设置仅在运行时知道的分数。

正式来说,我需要这样的函数:

pointFor :: PointsData -> Player -> Point
pointFor pd PlayerOne = pointsToPlayerOne pd
pointFor pd PlayerTwo = pointsToPlayerTwo pd

pointTo :: PointsData -> Player -> Point -> PointsData
pointTo pd PlayerOne p = pd { pointsToPlayerOne = p }
pointTo pd PlayerTwo p = pd { pointsToPlayerTwo = p }

正如所示,我的问题不是我无法实现这些功能。

但是,在我看来,它们确实像lens,所以我想知道我是否可以通过lens库获得该功能?

大多数镜头教程都会展示如何获取或设置更大数据结构的特定命名部分。这似乎不太适合我在这里想做的事情;相反,我试图获取或设置在运行时确定的子部分。

最佳答案

对抽象类型类的游览。您的 PointsDataPlayer 类型具有特殊关系。它有点像Map Player Point,其特殊性是对于Player每个可能值,总是相应的。在某种程度上,PointsData 就像一个“具体化函数”Player -> Point

如果我们使 PointsDataPoints 类型上具有多态性,它将适合 Representable类型类。我们会说 PointsDataPlayer“表示”。

Representable 通常可用作表格数据的接口(interface),例如 grids包。

<小时/>

因此,一种可能的解决方案是将 PointsData 转换为实际的 Map,但将实现隐藏在采用 Player -> Point< 的智能构造函数后面 函数为所有可能的键初始化它(它将对应于 Representabletabulate 方法)。

用户不应该能够从 map 中删除键。但我们可以利用Ixed Map 的实例提供遍历。

import Control.Lens
import Data.Map.Strict -- from "containers"

newtype PointsData = PointsData { getPoints :: Map Player Point }

init :: (Player -> Point) -> PointsData
init f = PointsData (Data.Map.Strict.fromList ((\p -> (p, f p)) <$> [minBound..maxBound]))


playerPoints :: Player -> Lens' PointsData Point
playerPoints pl = Control.Lens.singular (iso getPoints PointsData . ix pl)

关于haskell - 用于获取或设置由运行时参数确定的记录字段的镜头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56468091/

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