Board logo

標題: 有關 Option、Either 與 Try [列印本頁]

作者: caterpillar    時間: 2013-6-7 16:26     標題: 有關 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
作者: caterpillar    時間: 2013-6-7 16:32

話說每次寫硬式文章都騙不到幾個讚 … XD
作者: longbao738    時間: 2013-6-7 16:35

回復 1# caterpillar
一個多月後

這時間也太久了

作者: caterpillar    時間: 2013-6-7 16:42

因為有 iThome 要有備稿,而我大概有三、四篇備稿啊!…XD
作者: caterpillar    時間: 2013-6-7 16:45

在 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
作者: google117922654    時間: 2013-6-27 16:17

我覺得Try比Either不止更明確,它還可以用for comprehension
之前用Either用到把scalaz拿來用就為了Validation而已
作者: caterpillar    時間: 2013-6-27 17:08

回復 6# Steven Yang

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

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

函數式風格錯誤處理 http://www.ithome.com.tw/itadm/article.php?c=81622




歡迎光臨 CodeData 技術論譠 (http://codedata.com.tw/forum/) Powered by Discuz! 7.2