跳轉到內容

Haskell/解決方案/控制結構

來自 Wikibooks,開放的書籍,開放的世界

← 返回控制結構

case表示式

[編輯 | 編輯原始碼]
練習
使用 case 語句實現一個 fakeIf 函式,可以用來代替熟悉的 if 表示式。


fakeIf :: Bool -> a -> a -> a
fakeIf condition ifTrue ifFalse =
  case condition of
    True  -> ifTrue
    False -> ifFalse

控制操作,重新審視

[編輯 | 編輯原始碼]
練習
  1. 重新編寫 簡單輸入和輸出/控制操作 中的 "Haskell 問候語" 練習,這次使用 case 語句。
  2. 以下程式列印什麼?為什麼?
main =
 do x <- getX
    putStrLn x

getX =
 do return "My Shangri-La"
    return "beneath"
    return "the summer moon"
    return "I will"
    return "return"
    return "again"


1.

main = do
  putStrLn "Hello, what is your name?"
  name <- getLine
  case name of
      "Simon" -> greatlanguage
      "John"  -> greatlanguage
      "Phil"  -> greatlanguage
      "Koen"  -> putStrLn "I think debugging Haskell is fun."
      _       -> putStrLn "Sorry, I don't know you."
      where
      greatlanguage = putStrLn "I think Haskell is a great programming language."


2. 執行 main 將列印 "again"。記住,一系列 IO 操作的值與序列中最後一個操作的值相同。getX 也可以寫成

getX =
  do return "again"

甚至可以更短,寫成

getX = return "again"

因此,main 函式中的 x 值為 "again",然後將輸出到螢幕。

運算子

[編輯 | 編輯原始碼]
練習
  • Lambda 是避免定義不必要的獨立函式的一種好方法。將以下 let 或 where 繫結轉換為 lambda
    • map f xs where f x = x * 2 + 3
    • let f x y = read x + y in foldr f 1 xs
  • 部分應用只是 lambda 操作的語法糖。例如,(+2) 等效於 \x -> x + 2。以下部分應用會“反糖”成什麼?它們的型別是什麼?
    • (4+)
    • (1 `elem`)
    • (`notElem` "abc")

1.

  • 替換 fmap (\ x -> x * 2 + 3) xs
  • 替換 ffoldr (\ x y -> read x + y) 1 xs

2.

  • (4+)
    • 變成 (\ x -> 4 + x)
    • 型別為 Num a => a -> a
  • (1 `elem`)
    • 變成(\ x -> 1 `elem` x)
    • 也可以寫成 (\ x -> elem 1 x)
    • 型別為 Num a :: a -> Bool
      • 注意:完整型別為 (Foldable t, Eq a, Num a) => t a -> Bool,但還沒有講到這一點。
  • (`notElem` "abc")
    • 變成 (\ x -> x `notElem` "abc")
    • 也可以寫成 (\ x -> notElem x "abc")
    • 型別為 Char -> Bool
華夏公益教科書