top

有關 Option、Either 與 Try

在這篇文章中談到了 Optional:
http://www.codedata.com.tw/java/guava-tutorial-1-getting-started/

有在玩函數式程式設計語言的,像是 Scala,應該知道 Option,不過還有個 Either,事實上在 Haskell 中有 Maybe 及 Either…

有注意過 Scala 2.10 的,也會知道它增加了個 Try…

Option、Either 與 Try 的介紹,可以參考:
[Scala] 用 Option[T] 來避免 NullPointerException
[Scala] 比 Optiont[T] 再多一點的 Either[A, B]
[Scala] 比 Either[A, B] 再明確一點的 Try[T]

實際上,Scala 中的 try-catch 很有趣,它是運算式(Expression),會有傳回值,可以再參考一下:
[Scala] 2.10 新增的 Try 錯誤處理類別

看出什麼了嗎?Option、Either 或語意更明確的 Try,都是函數式風格的錯誤處理元素,所以我今天針對「函數式風格錯誤處理」寫了篇 iThome 專欄!…大概在一個多月後會出現在 iThome …XD

TOP

回復 6# Steven Yang

Either 基本上就是左值與右值,只不過右這個名字在英文是 Right,這是老外的幽默,就像是 ... Your left brain has nothing right ... You right brain has nothing left ... XD

雖然文件上都建議左值用來承載錯誤資訊,右值用來表示正確結果,不過確實還是用 Try 會更為明確,不過純函數式中沒有(或只是我沒看過)try ... catch 的觀念,因此從這點來看,純函數式中用 Either 是可以理解的。

TOP

我覺得Try比Either不止更明確,它還可以用for comprehension
之前用Either用到把scalaz拿來用就為了Validation而已

TOP

在 Java 中寫個 Try,然後配合 JDK8 Lambda 語法,大概像是這樣:
  1. abstract class Try<T> {
  2.     abstract boolean isSuccess();
  3.     boolean isFailure() { return ! isSuccess(); }
  4.     abstract T get();
  5.     abstract Exception resolve();
  6.     static <T> Try<T> tryIt(F<T> f) {
  7.         try { return new Success<T>(f.apply());
  8.         } catch(Exception e) { return new Failure<T>(e); }
  9.     }
  10. }

  11. final class Success<T> extends Try<T> {
  12.     private T value;
  13.     Success(T v) { this.value = v; }
  14.     boolean isSuccess() { return true;  }
  15.     T get() { return value; }
  16.     Exception resolve() { throw new IllegalStateException(); }
  17. }

  18. final class Failure<T> extends Try<T> {
  19.     private Exception e;
  20.     Failure(Exception e) { this.e = e; }
  21.    
  22.     boolean isSuccess() { return false;  }
  23.     T get() { throw new IllegalStateException(); }
  24.     Exception resolve() { return e; }
  25. }

  26. interface F<T> {
  27.     T apply();
  28. }

  29. public class Test {
  30.   public static void main(String[] args) {
  31.       Try<Integer> result = Try.tryIt(() -> Integer.parseInt(args[0]));
  32.       if(result.isSuccess()) {
  33.           System.out.println(result.get());
  34.       } else {
  35.           System.out.println(result.resolve());
  36.       }
  37.   }
  38. }
複製程式碼

當然,跟 Scala 比起來,還是囉嗦了一點,不過總是進步了一些…XD

TOP

因為有 iThome 要有備稿,而我大概有三、四篇備稿啊!…XD

TOP

回復 1# caterpillar
一個多月後

這時間也太久了

TOP

話說每次寫硬式文章都騙不到幾個讚 … XD

TOP