跳转到内容

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
华夏公益教科书