我是 F# 新手,正在尝试开发贪吃蛇游戏,如果这听起来很愚蠢,请原谅我。
目前,这是游戏的模型:
// value objects
type Position = int * int
type Block = { Position: Position }
type Tail = { Blocks: Block list }
type Direction =
| North
| South
| West
| East
//
// entities
type Snake = { Tail: Tail }
type World = { Snake: Snake }
//
为了让移动蛇时变得更简单,我想要每个 Direction
拥有自己的Position
,就像:
type Direction =
| North of Position (0, 1)
| South of Position (0, -1)
| West of Position (-1, 0)
| East of Position (0, 1)
所以我可以在这里应用它:
let moveSnakeHead direction snake =
// easily move the snake's head
// tail[0].x += direction.x, tail[0].y += direction.y
但是,在我看来这是不可能的of Position (x, y)
在受歧视的工会内部?
有人能解释一下为什么吗?我正在尽力学习类型。还有什么替代方案?
最佳答案
确保您清楚 F# 中值和类型之间的区别。对于刚接触 F# 的人来说,这是一个常见的陷阱,尤其是在受歧视的工会方面。
1
是 int
类型的值。
(1, 1)
是 (int * int)
类型的值。
当您定义 DU 类型时,每个 case 都可以保存某种类型的数据:
type DUType =
| DUCase1 of int
因此,每个 DU 案例可以包含任何 int
,而不仅仅是特定的 int
。
您的代码中还有一个类型别名:type Position = int * int
。这只是说你可以在任何地方写 Position
,它的含义与 int * int
相同。它实际上不是另一种类型。
因此,在您的代码中,您不能说 DU 案例必须始终包含特定的值。您需要编写一个函数,该函数接受 Direction
并返回 Position
:
type Direction =
| North
| South
| West
| East
let directionToPostion direction : Position =
match direction with
| North -> (0, 1)
| South -> (0, -1)
| West -> (-1, 0)
| East -> (0, 1)
您编写的任何 F# 代码通常始终处于 3 种“模式”:
- 值(value)
- 类型
- 模式(如模式匹配)
尝试确保您在任何给定时间都知道自己属于这三者中的哪一个。
关于f# - 受歧视工会内部的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64735519/