On this page:
maybe/  do
8.3

2.6 maybe/do

syntax

(maybe/do expr ...+)

 
expr = 普通表达式
  | 赋值表达式
  | 中断表达式
  | 副作用表过式
     
赋值表达式 = 
  | (let id = expr)
  | (id <- expr)
     
中断表达式 = 
  | (break)
  | (break )
     
副作用表过式 = 
  | (! 任意表达式 ...+)
自动处理空值语法,无论何种方式,经过maybe/do的结果必然是maybe?

在赋值表达式中,(id <- expr)这种形式,会对expr结果进行封装,如果是普通值(非Maybe),会以->maybe包装后再进行相关流程。(let)表达式就是纯粹赋值,没有多余处理流程。

Examples:
> (define (f n)
    (and (< n 5) n))
> (maybe/do
    (a <- (f 1))
    (b <- (f 2))
    (+ a b))

(Just 3)

> (maybe/do
    (a <- (f 1))
    (b <- (f 10))
    (+ a b))

(Nothing)

> (maybe/do
    (let a = (f 1))
    (let b = (f 10))
    (+ a b))

+: contract violation

  expected: number?

  given: #f

break可以中断操作,提前跳转整个代码块。它可以接受一个参数或无参数:接受一个参数,该参数自动封装成maybe?(除非已经是Maybe);无参数返回nothing

Examples:
> (maybe/do
    (a <- 1)
    (when (= a 1) (break 10))
    (! (displayln a))
    (add1 a))

(Just 10)

> (maybe/do
    (a <- 1)
    (unless (= a 10) (break))
    a)

(Nothing)

!仅仅用来处理副作用的代码。需要IO处理(如打印、读写文件),又不想中断整个操作,那么可以使用该形式表过式。不管它最终结果是什么,都不会中断后面代码!

Examples:
> (define (fmt x)
    (displayln x)
    #f)
> (maybe/do
    (a <- "hello")
    (b <- "world")
    (! (fmt a)
       (fmt b))
    (void))

hello

world

(Just #<void>)

> (maybe/do
    (a <- "hello")
    (b <- "world")
    (fmt a)
    (fmt b)
    (void))

hello

(Nothing)