gpt4 book ai didi

haskell - 在 Haskell 中为状态传递风格编写辅助函数吗?

转载 作者:行者123 更新时间:2023-12-04 17:00:02 24 4
gpt4 key购买 nike

我正在为纸牌游戏编写一些代码:

splitCards_ (x:xs) (a,b,c) | isGold x   = splitCards xs (a:x,b,c) 
| isAction x = splitCards xs (a,b:x,c)
| isVP x = splitCards xs (a,b,c:x)
splitCards_ [] (a,b,c) = (a,b,c)

splitCards xs = splitCards_ xs ([],[],[])

本质上,获取一张卡片列表,并根据卡片的类型将其拆分为三个不同的列表。 splitCards_通过递归更新它的参数来表示状态更新,然后 splitCards (实际函数)用于始终在三个特定类型卡片列表为空的情况下开始计算。

我相信这被称为状态传递风格,我很确定这是完全惯用的,但我更关心的是我必须定义一个辅助函数 splitCards_为了让它按照我想要的方式工作。正在创建像这个惯用的 Haskell 的辅助函数吗?有没有更干净的方法来写这个?是否有命名约定比在辅助函数名称的末尾加上下划线更可取?

最佳答案

是的,这是一种非常地道的风格。这是使函数尾递归的经典方法。 (尽管这在 Haskell 中不那么重要,而且稍微微妙一些)。

而且,制作辅助函数绝对是一件好事,也是许多常见模式的关键部分。如果你觉得有些东西更自然,那就去吧!除非它走极端,否则它有助于可读性。

我的主要建议是将辅助函数放入 where条款。这样,它只会在 main 函数的范围内可见,这清楚地表明它只是一个助手。你给辅助函数起的名字不太重要; splitCards_很好,但是 splitCards' (发音为“splitCards prime”)和 go (辅助函数的通用名称)会更常见。所以我会像这样重写你的代码:

splitCards xs = go xs ([],[],[]) 
where go (x:xs) (a, b, c) | isGold x = go xs (a:x,b,c)
| isAction x = go xs (a,b:x,c)
| isVP x = go xs (a,b,c:x)
go [] (a, b, c) = (a, b, c)

请注意,这些只是表面上的更改——您所做的从根本上来说是合理的。

两个命名选项( gosplitCards' )只是一个偏好问题。

我个人喜欢 go因为,一旦你习惯了这个约定,它就会清楚地表明某些东西只是一个辅助函数。从某种意义上说, go几乎更像是语法而不是它自己的函数;它的意思纯粹是从属于 splitCards功能。

别人不喜欢 go因为它有点神秘,有点随意。它也可能使您的代码的递归结构不太清楚,因为您在 go 上递归。而不是函数本身。

选择你认为最好看的东西。

关于haskell - 在 Haskell 中为状态传递风格编写辅助函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26685612/

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