學習軌道
/
F#
F#
/
練習
/
情人節
情人節

情人節

學習練習

簡介

差別聯合

差別聯合型別代表固定數量的具名案例。差別聯合的每個值都恰好對應其中一個具名案例。

差別聯合使用type關鍵字定義,各案例之間以管道(|)字元分隔:

type Season =
    | Spring
    | Summer
    | Autumn
    | Winter

差別聯合的每個案例都可以選擇性地帶有關聯資料,而且不同的案例可以帶有不同型態的資料。如果所有案例都沒有關聯資料,這個差別聯合就類似於其他語言通常所說的_列舉_。

type Number =
    | Integer of int
    | Float of float
    | Invalid

建立特定案例的值,可以藉由參照它的名稱來完成(例如Success)。由於案例名稱就只是建構函式,關聯資料可以像一般函式引數一樣傳入。如果另一個差別聯合定義了同名的案例,你就必須使用它的完整名稱(例如Result.Success)。

let byName = Integer 2
let byFullName = Number.Invalid

差別聯合具有_結構相等性_,也就是說,同一個案例且帶有相同(選用)資料的兩個值彼此等價。

雖然你可以使用if/elif/else運算式來處理差別聯合,但建議的處理方式是透過模式比對,並使用_識別碼模式_:

let describe number =
    match number with
    | Integer i -> sprintf "Integer: %d" i
    | Float d  -> sprintf "Float: %f" d
    | Invalid   -> "Invalid"

說明

在這個練習中,情人節到了,你和你的另一半打算一起做點開心的事。你的另一半有很多想法,現在要你為這些想法評分,好找出要進行的活動。

你的另一半提出了以下幾個想法:

  • 玩桌遊
  • 放鬆一下
  • 看電影
  • 上餐廳吃飯
  • 散步

你有 6 項任務,幫助你挑選情人節的活動。

1. 定義核准

你的另一半每提出一個想法,你都要從三種選項中擇一回應:「是」、「否」或「也許」。

定義Approval差別聯合,用下列 3 個案例來表示這些選項:Yes、No和Maybe。

2. 定義料理種類

你的另一半選了 2 間可能的餐廳:其中一間是韓式料理,另一間是土耳其料理。

定義Cuisine差別聯合,用下列 2 個案例來表示這些料理種類:Korean和Turkish。

3. 定義電影類型

可以選的電影多到數不清,所以為了縮小範圍,你的另一半也列出了自己想看的類型。

定義Genre差別聯合,用下列幾個案例來表示這些類型:Crime、Horror、Romance和Thriller。

4. 定義活動

如前所述,你的另一半想出了 5 種不同的活動:玩桌遊、放鬆一下、看電影、上餐廳吃飯和散步。

定義Activity差別聯合,用下列案例來表示這些活動類型:

  • BoardGame:沒有附帶資料。
  • Chill:沒有附帶資料。
  • Movie:以Genre作為附帶資料。
  • Restaurant:以Cuisine作為附帶資料。
  • Walk:以int作為附帶資料,代表要走的公里數。

5. 為活動評分

最後,你準備好要為另一半的想法評分了。以下是你對每個想法的感受:

  • 玩桌遊:「否」。
  • 放鬆一下:「否」。
  • 看電影:如果是浪漫愛情片就是「是」,否則「否」。
  • 上餐廳吃飯:如果是韓式料理就是「是」,如果是土耳其料理就是「也許」。
  • 散步:如果走不到 3 公里就是「是」;不到 5 公里就是「也許」;否則「否」。

實作一個名為rateActivity的函式,它接收一個Activity值,並根據上述的感受回傳對應的Approval:

rateActivity (Restaurant Turkish)
// => Maybe
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
F# Exercism

準備好開始 情人節 了嗎?

註冊 Exercism,透過 18 個概念148 個練習 和真人引導來學習並精通 F#,全部免費。