轨道
/
Gleam
Gleam
/
练习
/
情人节
情人节

情人节

学习练习

简介

自定义类型

在 Gleam 中,自定义类型用来定义新的数据类型。一个自定义类型可以有多个_变体_,每个变体都有自己的名字。

pub type Season {
  Spring
  Summer
  Autumn
  Winter
}

自定义类型的每个变体都可以选择性地携带一些数据,而且不同变体携带的数据类型可以不同。当变体携带数据时,它就被称为_记录_。

pub type Number {
  SomeInt(Int)
  SomeFloat(Float)
  Invalid
}

如果要为某个变体创建值,当它不包含额外数据时(Spring),直接引用它的名字即可;当它包含额外数据时(SomeInt(2)),则把它当作函数来调用。

let spring = Spring
let integerTwo = SomeInt(2)

自定义类型和 Gleam 中的其他所有东西一样,都具有_结构相等性_:也就是说,两个值只要属于同一个变体、携带的数据相同,就彼此等价。

Spring == Spring // -> True
Spring == Autumn // -> False
SomeInt(2) == SomeInt(2) // -> True
SomeInt(2) == SomeFloat(2.0) // -> False

使用 case 表达式,可以对自定义类型的变体进行模式匹配。

import gleam/int
import gleam/float

pub fn describe(flexible_number: Number) -> String {
  case flexible_number {
    SomeFloat(f) -> "Float: " <> float.to_string(f)
    SomeInt(i) -> "Int: " <> int.to_string(i)
    Invalid -> "Neither a float nor an int"
  }
}

说明

在这个练习里,今天是情人节,你和伴侣打算一起做点开心的事。你的伴侣有很多想法,现在请你给这些想法打分,好挑出要进行的活动。

你的伴侣提出了以下想法:

  • 玩桌游
  • 放松一下
  • 看电影
  • 去餐厅
  • 散步

你有六项任务,帮你选出情人节的活动。

1. 定义 Approval

对于伴侣提出的每个想法,你都要用三个选项之一来回应:yes、no 或 maybe。

定义Approval自定义类型,用以下三个构造子表示这些选项:Yes、No和Maybe。

2. 定义 Cuisine

你的伴侣选了两家可能去的餐厅:一家是韩式料理,另一家是土耳其料理。

定义Cuisine自定义类型,用以下两个构造子表示这两种料理:Korean和Turkish。

3. 定义 Genre

可选的电影非常多,为了缩小范围,你的伴侣还列出了电影的类型。

定义Genre自定义类型,用构造子表示以下类型:Crime、Horror、Romance和Thriller。

4. 定义 Activity

如前所述,你的伴侣想出了五种不同的活动:玩桌游、放松一下、看电影、去餐厅和散步。

定义Activity自定义类型来表示这些活动:

  • BoardGame:没有关联数据。
  • Chill:没有关联数据。
  • Movie:以它的Genre作为关联数据。
  • Restaurant:以它的Cuisine作为关联数据。
  • Walk:以Int作为关联数据,表示要步行的公里数。

5. 给活动评分

最后,你可以给伴侣的想法评分了。你对伴侣想法的态度如下:

  • 玩桌游:no。
  • 放松一下:no。
  • 看电影:如果是爱情片,就 yes;否则 no。
  • 去餐厅:如果是韩式料理,就 yes;如果是土耳其料理,就 maybe。
  • 散步:如果步行超过 11 公里,就 yes;如果超过 6 公里,就 maybe;否则 no。

实现一个名为rate_activity的函数,它接收一个Activity值,并根据上面的态度返回Approval:

rate_activity(Restaurant(Turkish))
// -> Maybe
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Gleam Exercism

准备好开始 情人节 了吗?

注册 Exercism,借助 33 个概念122 个练习 和真人导师指导,学习并掌握 Gleam,全部免费。