情人節

情人節

學習練習

簡介

代數資料型態(ADT)代表固定數量的具名情況。 ADT 的每個值都恰好對應到其中一個具名情況。

ADT 使用data關鍵字定義,各個情況之間以直立線(|)字元分隔。 如果所有情況都沒有附帶資料,這種 ADT 就類似其他語言通常所稱的列舉(或 enum)。

data Season
  = Spring
  | Summer
  | Autumn
  | Winter

ADT 的每個情況都可以選擇性地附帶資料,而且不同的情況可以有不同的資料型態。 當情況附帶資料時,就必須有建構子。

data Number
  = NInt Int      --'NInt' is the constructor for an Int Number.
  | NFloat Float  --'NFloat' is the constructor for an Float Number.
  | Invalid       --'Invalid' does not have data associated to it.

要為某個特定情況建立值,只要引用它的名稱即可(例如NInt 22)。 由於情況名稱本身只是建構子函式,附帶的資料可以像一般函式引數一樣傳入。

ADT 具有結構相等性,意思是同一個情況且附帶的(選用)資料也相同的兩個值,彼此是相等的。

雖然可以用if/else運算式來處理 ADT,但建議的做法是使用case敘述進行模式匹配:

add1 :: Number -> String
add1 number =
    case number of
      NInt    i -> show (i + 1)
      NFloat  f -> show (f + 1.0)
      Invalid   -> error "Invalid input"

說明

在這個練習中,今天是情人節,你正在規劃要和伴侶一起做什麼。你的伴侶有很多想法,並請你為這些想法評分,好找出最棒的活動。

以下是你的伴侶提出的想法:

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

你有六個任務,幫助你選出情人節的活動。

1. 定義認可

你的伴侶提出的每個想法,你都要用三種選項之一來回應:yes、no 或 maybe。

定義 Approval 代數資料型態,以下列三種案例來表示這些選項:Yes、No 或 Maybe。

2. 定義料理

你的伴侶選了兩間可能的餐廳:一間是韓國料理,另一間是土耳其料理。

定義 Cuisine 代數資料型態,以下列兩種案例來表示這兩間餐廳:Korean 或 Turkish。

3. 定義電影類型

可以選擇的電影非常多,所以為了縮小範圍,你的伴侶也列出了自己偏好的類型。

定義 Genre 代數資料型態,以下列幾個類型案例來表示:Crime、Horror、Romance 或 Thriller。

4. 定義活動

如前所述,你的伴侶想出了五種可能的活動:玩桌遊、放鬆一下、看電影、去餐廳吃飯和散步。

定義 Activity 代數資料型態來表示這些活動類型:

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

5. 為活動評分

最後,你準備好要為伴侶的想法評分了。 以下是你看待伴侶想法的感受:

  • 玩桌遊:no。
  • 放鬆一下:no。
  • 看電影:如果是浪漫愛情片,就是 yes;否則為 no。
  • 去餐廳吃飯:如果是韓國料理,就是 yes;如果是土耳其料理,就是 maybe。
  • 散步:如果走不到 3 公里,就是 yes;如果介於 3 到 5 公里(含),就是 maybe;否則為 no。

實作一個名為 rateActivity 的函式,接受一個 Activity 值,並依據上述感受回傳 Approval。 例如:

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

準備好開始 情人節 了嗎?

註冊 Exercism,透過 107 個練習 和真人引導來學習並精通 Haskell,全部免費。