Haskell 哈斯克尔镜头:如何优雅地测试列表项
然后我对上述数据类型进行Haskell 哈斯克尔镜头:如何优雅地测试列表项,haskell,haskell-lens,Haskell,Haskell Lens,然后我对上述数据类型进行makelents 退出游戏的条件是玩家手中的所有牌都已收回。 所以在我的游戏StateT monad中,我访问所有的CardStatus并测试它们。由于我是新来的镜头,我想知道什么是优雅的方式来写这个。 在镜头操作员的森林中迷失了一点。该模块有许多用于测试镜头/折叠/遍历目标的组合器:(用于检查棱镜是否匹配),noneOf 在您的示例中(假设我们还有forCardStatus),我们可以执行以下操作: data Game = Game { _players :: [P
makelents
退出游戏的条件是玩家手中的所有牌都已收回。
所以在我的游戏StateT monad中,我访问所有的CardStatus并测试它们。由于我是新来的镜头,我想知道什么是优雅的方式来写这个。
在镜头操作员的森林中迷失了一点。该模块有许多用于测试镜头/折叠/遍历目标的组合器:(用于检查棱镜是否匹配),noneOf
在您的示例中(假设我们还有forCardStatus
),我们可以执行以下操作:
data Game = Game {
_players :: [Player]
}
data Player = Player {
_cards :: [Card]
}
data Card = Card {
_status :: CardStatus
}
data CardStatus = Face | Back
此外,要找出哪些玩家有赢家,我们可以使用:
这些函数类似于典型的列表函数,但可以直接应用于褶皱,因此它们不会把你从lensy世界中拉出来。例如,我们可以继续用另一个折叠组合赢家
该模块有许多用于测试镜头/折叠/遍历目标的组合器:(用于检查棱镜是否匹配),无
在您的示例中(假设我们还有forCardStatus
),我们可以执行以下操作:
data Game = Game {
_players :: [Player]
}
data Player = Player {
_cards :: [Card]
}
data Card = Card {
_status :: CardStatus
}
data CardStatus = Face | Back
此外,要找出哪些玩家有赢家,我们可以使用:
这些函数类似于典型的列表函数,但可以直接应用于褶皱,因此它们不会把你从lensy世界中拉出来。例如,我们可以继续使用另一个折叠来组合赢家
,,这样您就需要一个光学系统来告诉您是否所有的卡都是背面的。道德上
winners :: Fold Game Player
winners = players.folded.filtered (allOf (cards.folded.status) (has _Back))
这显然是某种形式
allBack :: Getter Player Bool
…不要再进一步了,问问GHC这是否有意义:
allBack = cards . _
好的,听起来很合理。那签名看上去很可疑是旧的
$ ghc wtmpf-file11136.hs
wtmpf-file11136.hs:26:19: error:
• Found hole: _ :: (Bool -> f Bool) -> [Card] -> f [Card]
给予
allBack = cards . traverse . _
好的,这里的问题是Getter
应该立即关注单个元素。但实际上,我们首先需要对多个元素进行压缩(折叠)成一个Bool
。这意味着我们需要将签名从Getter
更改为Fold
(这在引擎盖下提供了Applicative
约束):
好的,这是有道理的——我们指定要以某种方式减少列表中的布尔值,但减少列表中布尔值的方法不止一种。在我们的例子中,我们希望它们都是真的,即我们需要从Bool
切换到:
好的,看起来不错。现在我们需要指定要检查的卡的属性。关于它的地位:
wtmpf-file11136.hs:26:30: error:
• Found hole: _ :: (All -> f All) -> Card -> f Card
在这一点上,我们现在需要一个决定,也就是说,我们需要扔进一个棱镜。有人可能会认为这是\u Back
棱镜,但实际上这代表了“无聊”的情况。我们想要触发故障的情况是\u Face
:
• Found hole: _ :: (All -> f All) -> CardStatus -> f CardStatus
在这里,所有需要做的就是宣布此\u面
是一个失败案例:
• Found hole: _ :: (All -> f All) -> () -> f ()
这是可行的,尽管正如威廉·范·昂森评论的那样,纯镜头并不是最佳选择。将其作为一个函数来编写更为合理,可以取得良好的平衡。因此,您需要一个光学系统,它可以告诉您是否所有卡都返回了
。道德上
winners :: Fold Game Player
winners = players.folded.filtered (allOf (cards.folded.status) (has _Back))
这显然是某种形式
allBack :: Getter Player Bool
…不要再进一步了,问问GHC这是否有意义:
allBack = cards . _
好的,听起来很合理。那签名看上去很可疑是旧的
$ ghc wtmpf-file11136.hs
wtmpf-file11136.hs:26:19: error:
• Found hole: _ :: (Bool -> f Bool) -> [Card] -> f [Card]
给予
allBack = cards . traverse . _
好的,这里的问题是Getter
应该立即关注单个元素。但实际上,我们首先需要对多个元素进行压缩(折叠)成一个Bool
。这意味着我们需要将签名从Getter
更改为Fold
(这在引擎盖下提供了Applicative
约束):
好的,这是有道理的——我们指定要以某种方式减少列表中的布尔值,但减少列表中布尔值的方法不止一种。在我们的例子中,我们希望它们都是真的,即我们需要从Bool
切换到:
好的,看起来不错。现在我们需要指定要检查的卡的属性。关于它的地位:
wtmpf-file11136.hs:26:30: error:
• Found hole: _ :: (All -> f All) -> Card -> f Card
在这一点上,我们现在需要一个决定,也就是说,我们需要扔进一个棱镜。有人可能会认为这是\u Back
棱镜,但实际上这代表了“无聊”的情况。我们想要触发故障的情况是\u Face
:
• Found hole: _ :: (All -> f All) -> CardStatus -> f CardStatus
在这里,所有需要做的就是宣布此\u面
是一个失败案例:
• Found hole: _ :: (All -> f All) -> () -> f ()
这是可行的,尽管正如威廉·范·昂森评论的那样,纯镜头并不是最佳选择。仅将其作为一个函数来编写更为合理,可以达到很好的平衡。我不太明白这与镜头有什么关系,您可以定义一个函数来测试所有状态是否为黑色。我不太明白这与镜头有什么关系,您可以定义一个函数来测试所有状态是否为黑色。感谢您展示思考过程。你刚刚给我看了一大堆新东西要学。谢谢你展示了思考过程。你刚刚给我看了一大堆新东西要学。