Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
CI/CD Á÷Ë®Ïß´´½¨·½·¨£ºMonad¡¢Arrow »¹ÊÇ Dart £¿
 
×÷ÕߣºThomas Leonard ÒëÕߣºÎâÁôÆÂ
  2081  次浏览      29
2021-5-13 
 
±à¼­ÍƼö:
±¾ÎĽ«ÓÃÈýÖÖ·½·¨À´´´½¨ CI/CD Á÷Ë®Ïß¡£Monad ²»ÄܶÔÁ÷Ë®Ïß½øÐо²Ì¬·ÖÎö£¬Arrow Óï·¨ºÜÄÑÓã¬ÎÒ³ÆÖ®Îª Dart£¨²»ÖªµÀËüÊÇ·ñÒѾ­ÓÐÃû×ÖÁË£©µÄÒ»ÖÖÇáÁ¿¼¶µÄ Arrow ·½·¨¿ÉÒÔÏñ Arrow Ò»Ñù½øÐо²Ì¬·ÖÎö£¬µ«Óï·¨±È Monad ¸ü¼òµ¥¡£
±¾ÎÄÀ´×ÔÓÚinfoq£¬ÓÉ»ðÁú¹ûÈí¼þAnna±à¼­ÍƼö¡£

ÎÒÐèÒª¹¹½¨Ò»¸öÓÃÓÚ´´½¨ CI/CD Á÷Ë®ÏßµÄϵͳ¡£ËüÆð³õÊÇΪÁ˹¹½¨Ò»¸ö CI ϵͳ£¬²âÊÔ Github É쵀 OCaml ÏîÄ¿£¨Õë¶Ô¶à¸ö°æ±¾µÄ OCaml ±àÒëÆ÷ºÍ¶à¸ö²Ù×÷ϵͳ£¬²âÊÔÿ¸öÌá½»£©¡£ÏÂÃæÊÇÒ»¸ö¼òµ¥µÄÁ÷Ë®Ïߣ¬»ñȡij¸ö Git ·ÖÖ§×îеÄÌá½»£¬¹¹½¨£¬²¢Ö´ÐвâÊÔÓÃÀý¡£

¡¾ÒëÕß×¢¡¿CI/CD£º³ÖÐø¼¯³É£¨Continuous Integration£©ºÍ³ÖÐø²¿Êð£¨Continuous Deployment£©¼ò³Æ£¬Ö¸ÔÚ¿ª·¢¹ý³ÌÖÐ×Ô¶¯Ö´ÐÐһϵÁнű¾À´¼õµÍ¿ª·¢ÒýÈë bug µÄ¸ÅÂÊ£¬ÔÚдúÂë´Ó¿ª·¢µ½²¿ÊðµÄ¹ý³ÌÖУ¬¾¡Á¿¼õÉÙÈ˹¤µÄ½éÈë¡£

ÕâÀïµÄÅäÉ«±êʶÊÇ£ºÂÌÉ«µÄ·½¿òÊÇÒѾ­Íê³É£¬³ÈÉ«µÄÊÇÕýÔÚ½øÐУ¬»ÒÉ«µÄÒâζ×ÅÕâÒ»²½»¹²»ÄÜ¿ªÊ¼¡£

ÕâÀïÓÐÒ»¸öÉÔ΢¸´ÔÓµãµÄÀý×Ó£¬Ëü»¹ÏÂÔØÁËÒ»¸ö Docker »ù´¡¾µÏñ£¬Ê¹ÓÃÁ½¸ö²»Í¬°æ±¾µÄ OCaml ±àÒëÆ÷²¢Ðй¹½¨Ìá½»£¬È»ºó²âÊԵõ½µÄ¾µÏñ¡£ºì¿ò±íʾ´Ë²½Öèʧ°Ü£º

Ò»¸ö¸ü¸´ÔÓµÄÀý×ÓÊDzâÊÔÏîÄ¿±¾Éí£¬È»ºóËÑË÷ÒÀÀµËüµÄÆäËûÏîÄ¿£¬²¢¸ù¾Ýа汾²âÊÔÕâЩÏîÄ¿£º

ÔÚÕâÀԲȦÒâζ×ÅÔÚ¼ì²é·´ÏòÒÀÀµÏî֮ǰ£¬ÎÒÃÇÓ¦¸ÃµÈ´ý²âÊÔͨ¹ý¡£

ÎÒÃÇ¿ÉÒÔÓà YAML »òÀàËÆµÄ·½·¨À´ÃèÊöÕâЩ¹ÜµÀ£¬µ«Õ⽫ÊǷdz£ÓÐÏ޵ġ£Ïà·´£¬ÎÒ¾ö¶¨Ê¹ÓÃÒ»ÖÖÌØ¶¨ÓÚÁìÓòµÄǶÈëʽÓïÑÔ£¬ÕâÑùÎÒÃǾͿÉÒÔÃâ·ÑʹÓÃËÞÖ÷ÓïÑÔµÄÌØÐÔ£¨ÀýÈç×Ö·û´®²Ù×÷¡¢±äÁ¿¡¢º¯Êý¡¢µ¼Èë¡¢ÀàÐͼì²éµÈ£©¡£

×îÃ÷ÏԵķ½·¨ÊÇʹÿ¸ö¿ò³ÉΪÕýÔòº¯Êý¡£È»ºóÉÏÃæµÄµÚÒ»¸öÀý×Ó¿ÉÒÔÊÇ£¨ÕâÀʹÓà OCaml Óï·¨£©£º

let example1 commit =
let src = fetch commit in
let image = build src in
test image

µÚ¶þ¸ö¿ÉÄÜÊÇ£º

let example2 commit =
let src = fetch commit in
let base = docker_pull "ocaml/opam2" in
let build ocaml_version =
let dockerfile = make_dockerfile ~base ~ocaml_version in
let image = build ~dockerfile src ~label:ocaml_version in
test image
in
build "4.07";
build "4.08"

µÚÈý¸ö¿ÉÄÜÊÇÕâÑùµÄ£º

let example3 commit =
let src = fetch commit in
let image = build src in
test image;
let revdeps = get_revdeps src in
List.iter example1 revdeps

²»¹ý£¬ÎÒÃÇÏëÔÚÓïÑÔÖÐÌí¼ÓһЩ¸½¼Ó¹¦ÄÜ£º

¹ÜµÀ²½ÖèÓ¦¾¡¿ÉÄܲ¢ÐÐÔËÐС£ÉÏÃæµÄ example2 º¯Êý½«Ò»´ÎÍê³ÉÒ»¸ö¹¹½¨¡£

¹ÜµÀ²½ÖèÓ¦ÔÚÆäÊäÈë¸ü¸ÄÊ±ÖØÐ¼ÆËã¡£e¡¢ µ±ÎÒÃÇ×÷³öеijÐŵʱ£¬ÎÒÃÇÐèÒªÖØ½¨¡£

Óû§Ó¦¸ÃÄܹ»²é¿´Ã¿¸ö²½ÖèµÄ½ø¶È¡£

Óû§Ó¦¸ÃÄܹ»ÎªÈκβ½Öè´¥·¢Öؽ¨¡£

ÎÒÃÇÓ¦¸ÃÄܹ»´Ó´úÂëÖÐ×Ô¶¯Éú³Éͼ±í£¬ÕâÑùÎÒÃǾͿÉÒÔÔÚÔËÐйܵÀ֮ǰ¿´µ½Ëü½«×öʲô¡£

Ò»²½µÄʧ°Ü²»Ó¦¸ÃʹÕû¸ö¹ÜµÀÍ£Ö¹¡£

¶ÔÓÚÕâÆª²©¿ÍÎÄÕÂÀ´Ëµ£¬È·Çеĸ½¼Ó¹¦Äܲ¢²»ÖØÒª£¬Òò´ËΪÁ˼òµ¥Æð¼û£¬ÎÒ½«Öصã·ÅÔÚͬʱÔËÐв½ÖèÉÏ¡£

Monad ·½·¨

¡¾ÒëÕß×¢¡¿Monad£ºº¯×Ó£¬µ¥×Ó£¬À´×Ô Haskell ±à³ÌÓïÑÔ£¬ÊǺ¯Êýʽ±à³ÌÖУ¬Ò»ÖÖ¶¨Ò彫º¯Êý£¨º¯×Ó£©×éºÏÆðÀ´µÄ½á¹¹·½Ê½£¬Ëü³ýÁË·µ»ØÖµÒÔÍ⣬»¹ÐèÒªÒ»¸öÉÏÏÂÎÄ¡£³£¼ûµÄ Monad ÓмÆËãÈÎÎñ£¬·ÖÖ§ÈÎÎñ£¬»òÕß I/O ²Ù×÷¡£

Èç¹ûûÓжîÍâµÄ¹¦ÄÜ£¬ÎÒÃÇÓÐÈçϹ¦ÄÜ£º

val fetch : commit -> source
val build : source -> image

Äú¿ÉÒÔ½«ÆäÀí½âΪ¡°build ÊÇÒ»¸ö»ñȡԴֵ²¢·µ»Ø£¨Docker£©¾µÏñµÄº¯Êý¡±¡£

ÕâЩº¯ÊýºÜÈÝÒ××éºÏÔÚÒ»Æð£¬ÐγÉÒ»¸ö¸ü´óµÄº¯ÊýÀ´»ñÈ¡Ìá½»²¢¹¹½¨Ëü£º

let fab c =
let src = fetch c in
build src

ÎÒÃÇ»¹¿ÉÒÔ½«ÆäËõ¶ÌΪ build£¨fetch c£©»ò fetch c |>build¡£OCaml ÖеÄ|>£¨pipe£©ÔËËã·ûÖ»µ÷ÓÃÆäÓÒ²àµÄº¯Êý£¬¶ø²ÎÊýÔÚÆä×ó²à¡£

ΪÁ˽«ÕâЩº¯ÊýÀ©Õ¹Îª²¢·¢µÄ£¬ÎÒÃÇ¿ÉÒÔÈÃËüÃÇ·µ»Ø³Ðŵ£¬ÀýÈ磬

val fetch : commit -> source promise
val build : source -> image promise

µ«ÊÇÏÖÔÚÎÒÃÇÎÞ·¨Ê¹Óà let£¨»ò|>£©ÇáËÉ×éºÏËüÃÇ£¬ÒòΪ fetch µÄÊä³öÀàÐÍÓë build µÄÊäÈ벻ƥÅä¡£

µ«ÊÇ£¬ÎÒÃÇ¿ÉÒÔ¶¨ÒåÒ»¸öÀàËÆµÄ²Ù×÷£¬let£¨»ò>>=£©À´´¦Àí³Ðŵ¡£ËüÁ¢¼´·µ»Ø¶Ô×îÖÕ½á¹ûµÄ³Ðŵ£¬²¢ÔÚµÚÒ»¸ö³ÐŵʵÏÖºóµ÷Óà let* µÄÖ÷Ìå¡£ÄÇôÎÒÃÇÓУº

let fab c =
let* src = fetch c in
build src

»»¾ä»°Ëµ£¬Í¨¹ýÔÚÖÜΧÈöÉϼ¸¸öÐǺÅ×Ö·û£¬ÎÒÃÇ¿ÉÒÔ½«¼òµ¥µÄ¾É¹ÜµÀ±ä³ÉÒ»¸öеIJ¢·¢¹ÜµÀ£¡Ê¹Óà let* ±àд promise returning º¯ÊýµÄʱ¼ä¹æÔòÓëʹÓà let ±àд³£¹æº¯ÊýµÄʱ¼ä¹æÔòÍêÈ«Ïàͬ£¬Òò´ËʹÓà promise ±àд³ÌÐòÓë±àд³£¹æ³ÌÐòÒ»Ñù¼òµ¥¡£

½ö½öʹÓà let *²»»áÔÚÎÒÃǵĹܵÀÖÐÌí¼ÓÈκβ¢·¢£¨ËüÖ»ÔÊÐíËüÓëÆäËû´úÂë²¢·¢Ö´ÐУ©¡£µ«ÊÇÎÒÃÇ¿ÉÒÔΪ´Ë¶¨Òå¶îÍâµÄº¯Êý£¬±ÈÈç all Ò»´Î¼ÆËãÒ»¸öÁбíÖеÄÿ¸ö³Ðŵ£¬»òÕßʹÓà and ÔËËã·ûָʾÁ½¸öÊÂÎïÓ¦¸Ã²¢ÐÐÔËÐУº

³ýÁË´¦Àí³ÐŵÍ⣬ÎÒÃÇ»¹¿ÉÒÔΪ¿ÉÄÜ·µ»Ø´íÎóµÄº¯Êý£¨Ö»ÓÐÔÚµÚÒ»¸öÖµ³É¹¦Ê±²Åµ÷Óà let µÄÖ÷Ì壩»òΪʵʱ¸üУ¨Ã¿´ÎÊäÈë¸ü¸Äʱ¶¼µ÷ÓÃÖ÷Ì壩»òΪËùÓÐÕâЩ¶«Î÷Ò»Æð¶¨Òå let*¡£ÕâÊǵ¥×ӵĻù±¾¸ÅÄî¡£

ÕâÆäʵºÜ¹ÜÓá£ÔÚ 2016 Ä꣬ÎÒÓÃÕâÖÖ·½·¨×öÁË DataKitCI£¬Ëü×î³õÓÃÓÚ Docker-for-Mac É쵀 CI ϵͳ¡£Ö®ºó£¬Madhavapeddy ÓÃËü´´½¨ÁË opam-repo-ci£¬ÕâÊÇ opam-repository É쵀 CI ϵͳ£¬OCaml ÉÏÖ÷ÒªµÄÈí¼þ²Ö¿â¡£Õ⽫¼ì²éÿ¸öÐ嵀 PR ÒԲ鿴ËüÌí¼Ó»òÐÞ¸ÄÁËÄÄЩ°ü£¬Õë¶Ô¶à¸ö OCaml ±àÒëÆ÷°æ±¾ºÍ Linux ·¢Ðа棨Debian¡¢Ubuntu¡¢Alpine¡¢CentOS¡¢Fedora ºÍ OpenSUSE£©²âÊÔÿ¸ö°ü£¬È»ºó¸ù¾Ý¸ü¸ÄµÄ°ü²éÕÒËùÓаüµÄËùÓа汾£¬²¢²âÊÔÕâЩ°æ±¾¡£

ʹÓà monad µÄÖ÷ÒªÎÊÌâÊÇÎÒÃDz»ÄܶԹܵÀ½øÐо²Ì¬·ÖÎö¡£¿¼ÂÇÉÏÃæµÄ example2 º¯Êý¡£ÔÚ²éѯ GitHub ÒÔ»ñµÃ²âÊÔÌύ֮ǰ£¬ÎÒÃÇÎÞ·¨ÔËÐиú¯Êý£¬Òò´Ë²»ÖªµÀËü½«×öʲô¡£Ò»µ©ÎÒÃÇÓÐÁË commit£¬ÎÒÃǾͿÉÒÔµ÷Óà example2commit£¬µ«ÊÇÔÚ fetch ºÍ docker_pull ²Ù×÷Íê³É֮ǰ£¬ÎÒÃÇÎÞ·¨¼ÆËã let* µÄÖ÷ÌåÀ´ÕÒ³ö¹ÜµÀ½ÓÏÂÀ´½«×öʲô¡£

»»ÑÔÖ®£¬ÎÒÃÇÖ»ÄÜ»æÖÆÍ¼±í£¬ÏÔʾÒѾ­Ö´ÐлòÕýÔÚÖ´ÐеĹܵÀ룬²¢ÇÒ±ØÐëʹÓÃºÍ * ÊÖ¶¯Ö¸Ê¾²¢·¢µÄ»ú»á¡£

Arrow ·½·¨

Arrow ʹ¹ÜµÀµÄ¾²Ì¬·ÖÎö³ÉΪ¿ÉÄÜ¡£¶ø²»ÊÇÎÒÃǵÄÒ»Ôªº¯Êý£º

val fetch : commit -> source promise
val build : source -> image promise

ÎÒÃÇ¿ÉÒÔ¶¨Òå¼ýÍ·ÀàÐÍ£º

type ('a, 'b) arrow
val fetch : (commit, source) arrow
val build : (source, image) arrow

a£¨'a£¬'b£©arrow ÊÇÒ»¸ö½ÓÊÜ a ÀàÐÍÊäÈë²¢Éú³É b ÀàÐͽá¹ûµÄ¹ÜµÀ¡£Èç¹ûÎÒÃǶ¨ÒåÀàÐÍ£¨'a£¬'b£©arrow='a->'b promise£¬ÔòÕâÓëÒ»Ôª°æ±¾Ïàͬ¡£µ«ÊÇ£¬ÎÒÃÇ¿ÉÒÔ½«¼ýÍ·ÀàÐͳéÏ󻯣¬²¢¶ÔÆä½øÐÐÀ©Õ¹£¬ÒÔ´æ´¢ÎÒÃÇÐèÒªµÄÈκξ²Ì¬ÐÅÏ¢¡£ÀýÈ磬ÎÒÃÇ¿ÉÒÔ±ê¼Ç¼ýÍ·£º

type ('a, 'b) arrow = {
f : 'a -> 'b promise;
label : string;
}

ÕâÀ¼ýÍ·ÊÇÒ»¸ö¼Ç¼¡£f ÊǾɵÄÒ»Ôªº¯Êý£¬label ÊÇ¡°¾²Ì¬·ÖÎö¡±¡£

Óû§¿´²»µ½ arrow ÀàÐ͵ÄÄÚ²¿£¬±ØÐëʹÓà arrow ʵÏÖÌṩµÄº¯ÊýÀ´¹¹½¨¹ÜµÀ¡£ÓÐÈý¸ö»ù±¾¹¦ÄÜ¿ÉÓãº

val arr : ('a -> 'b) -> ('a, 'b) arrow
val ( >>> ) : ('a, 'b) arrow -> ('b, 'c) arrow -> ('a, 'c) arrow
val first : ('a, 'b) arrow -> (('a * 'c), ('b * 'c)) arrow

arr ½ÓÊÜ´¿º¯Êý²¢¸ø³öµÈ¼ÛµÄ¼ýÍ·¡£¶ÔÓÚÎÒÃǵijÐŵʾÀý£¬ÕâÒâζ׿ýÍ··µ»ØÒѾ­ÊµÏֵijÐŵ¡£>>>°ÑÁ½¸ö¼ýÍ·Á¬ÔÚÒ»Æð¡£Ê×ÏÈ´Ó¡°a¡±µ½¡°b¡±È¡Ò»¸ö¼ýÍ·£¬¸ÄΪ³É¶ÔʹÓ᣸öԵĵÚÒ»¸öÔªËØ½«Óɸø¶¨µÄ¼ýÍ·´¦Àí£¬µÚ¶þ¸ö×é¼þ½«Ô­·â²»¶¯µØ·µ»Ø¡£

ÎÒÃÇ¿ÉÒÔÈÃÕâЩ²Ù×÷×Ô¶¯´´½¨´øÓÐÊʵ± f ºÍ label ×ֶεÄмýÍ·¡£ÀýÈ磬ÔÚ a>>>b ÖУ¬½á¹û label ×ֶοÉÒÔÊÇ×Ö·û´®{a.label}>>{b.label}¡£ÕâÒâζ×ÅÎÒÃÇ¿ÉÒÔÏÔʾ¹ÜµÀ£¬¶ø²»±ØÏÈÔËÐÐËü£¬Èç¹ûÐèÒªµÄ»°£¬ÎÒÃÇ¿ÉÒÔºÜÈÝÒ×µØÓøü½á¹¹»¯µÄÄÚÈÝÌæ»» label¡£

ÎÒÃǵĵÚÒ»¸öÀý×ÓÊÇ£º

let example1 commit =
let src = fetch commit in
let image = build src in
test image

to

let example1 =
fetch >>> build >>> test

ËäÈ»ÎÒÃDz»µÃ²»·ÅÆú±äÁ¿Ãû£¬µ«ÕâËÆºõºÜÁîÈËÓä¿ì¡£µ«ÊÂÇ鿪ʼ±äµÃ¸´ÔÓ£¬ÓÐÁ˸ü´óµÄÀý×Ó¡£ÀýÈç 2£¬ÎÒÃÇÐèÒª¶¨Ò弸¸ö±ê×¼×éºÏ£º

(** Process the second component of a tuple, leaving the first unchanged. *)
let second f =
let swap (x, y) = (y, x) in
arr swap >>> first f >>> arr swap
(** [f *** g] processes the first component of a pair with [f] and the second
with [g]. *)
let ( *** ) f g =
first f >>> second g
(** [f &&& g] processes a single value with [f] and [g] in parallel and
returns a pair with the results. *)
let ( &&& ) f g =
arr (fun x -> (x, x)) >>> (f *** g)

Then, example2 changes from:

let example2 commit =
let src = fetch commit in
let base = docker_pull "ocaml/opam2" in
let build ocaml_version =
let dockerfile = make_dockerfile ~base ~ocaml_version in
let image = build ~dockerfile src ~label:ocaml_version in
test image
in
build "4.07";
build "4.08"

to:

let example2 =
let build ocaml_version =
first (arr (fun base -> make_dockerfile ~base ~ocaml_version))
>>> build_with_dockerfile ~label:ocaml_version
>>> test
in
arr (fun c -> ((), c))
>>> (docker_pull "ocaml/opam2" *** fetch)
>>> (build "4.07" &&& build "4.08")
>>> arr (fun ((), ()) -> ())

ÎÒÃÇÒѾ­¶ªÊ§ÁË´ó¶àÊý±äÁ¿Ãû£¬¶ø²»µÃ²»Ê¹ÓÃÔª×飬¼ÇסÎÒÃǵÄÖµÔÚÄÄÀï¡£ÕâÀïÓÐÁ½¸öÖµ²¢²»ÊǺÜÔã¸â£¬µ«ÊÇËæ×Ÿü¶àµÄÖµ±»Ìí¼Ó²¢ÇÒÎÒÃÇ¿ªÊ¼Ç¶Ì×Ôª×飬Ëü±äµÃ·Ç³£À§ÄÑ¡£ÎÒÃÇ»¹Ê§È¥ÁËÔÚ build~dockerfile src ÖÐʹÓÿÉÑ¡±ê¼Ç²ÎÊýµÄÄÜÁ¦£¬¶øÊÇÐèҪʹÓÃÒ»¸öвÙ×÷£¬¸Ã²Ù×÷½ÓÊÜ dockerfile ºÍÔ´µÄÔª×é¡£

¼ÙÉèÏÖÔÚÔËÐвâÊÔÐèÒª´ÓÔ´´úÂë»ñÈ¡²âÊÔÓÃÀý¡£ÔÚԭʼ´úÂëÖУ¬ÎÒÃÇÖ»ÐèʹÓãºsrc ½«²âÊÔͼÏñ¸ü¸ÄΪ²âÊÔͼÏñ¡£ÔÚ arrow °æ±¾ÖУ¬ÎÒÃÇÐèÒªÔÚÉú³É²½Öè֮ǰ¸´ÖÆÔ´´úÂ룬ʹÓôø dockerfile µÄ first build_ ÔËÐÐÉú³É£¬²¢È·±£²ÎÊýÊÇвâÊÔʹÓõÄÕýÈ··½·¨¡£

Dart ·½·¨

ÎÒ¿ªÊ¼»³ÒÉÊÇ·ñÓÐÒ»ÖÖ¸ü¼òµ¥µÄ·½·¨À´ÊµÏÖÓë¼ýÍ·ÏàͬµÄ¾²Ì¬·ÖÎö£¬µ«ÊÇûÓÐÎÞµãÓï·¨£¬¶øÇÒËÆºõÓС£¿¼ÂÇʾÀý 1 µÄÒ»Ôª°æ±¾¡£ÎÒÃÇÓУº

val build : source -> image promise
val test : image -> results promise
let example1 commit =
let* src = fetch commit in
let* image = build src in
test image

Èç¹ûÄã²»ÖªµÀÃÉÄÈ×ȵÄÊ£¬Ä㻹ÓбðµÄ°ì·¨¡£Äú¿ÉÒÔ¶¨Òå build ºÍ test£¬½« promises ×÷ΪÊäÈ룬¶ø²»ÊÇʹÓà let* µÈ´ý»ñÈ¡Íê³É£¬È»ºóʹÓÃÔ´µ÷Óà build£º

val build : source promise -> image promise
val test : image promise -> results promise

±Ï¾¹£¬fetching ¸øÁËÄãÒ»¸öÔ´´úÂë³Ðŵ£¬ÄãÏëÒªÒ»¸öͼÏñ³Ðŵ£¬ËùÒÔÕâ¿´ÆðÀ´ºÜ×ÔÈ»¡£ÎÒÃÇÉõÖÁ¿ÉÒÔÒÔ³ÐŵΪÀý¡£È»ºó¿´ÆðÀ´ÊÇÕâÑùµÄ£º

let example1 commit =
let src = fetch commit in
let image = build src in
test image

ºÜºÃ£¬ÒòΪËüºÍÎÒÃǸտªÊ¼µÄ¼òµ¥°æ±¾ÊÇÒ»ÑùµÄ¡£ÎÊÌâÊÇЧÂʵÍÏ£º

ÎÒÃÇÓóÐŵµÄ·½Ê½µ÷Óà example1£¨ÎÒÃÇ»¹²»ÖªµÀËüÊÇʲô£©¡£

ÎÒÃDz»±ØµÈ´ýÕÒ³öÒª²âÊÔµÄÌá½»£¬¶øÊǵ÷Óà fetch£¬»ñȡij¸öÔ´µÄ³Ðŵ¡£

²»ÐèÒªµÈ´ý»ñȡԴ´úÂ룬ÎÒÃǾ͵÷Óà build£¬»ñȡͼÏñµÄ³Ðŵ¡£

²»Óõȴý¹¹½¨£¬ÎÒÃǵ÷Óà test£¬µÃµ½½á¹ûµÄ³Ðŵ¡£

ÎÒÃÇÁ¢¼´·µ»Ø²âÊÔ½á¹ûµÄ×îÖÕ³Ðŵ£¬µ«ÎÒÃÇ»¹Ã»ÓÐ×öÈκÎÕæÕýµÄ¹¤×÷¡£Ïà·´£¬ÎÒÃǽ¨Á¢ÁËÒ»³¤´®µÄ³Ðŵ£¬ÀË·ÑÁ˼ÇÒä¡£

µ«ÊÇ£¬ÔÚÕâÖÖÇé¿öÏ£¬ÎÒÃÇÏ£ÍûÖ´Ðо²Ì¬·ÖÎö¡£i¡¢ ÎÒÃÇÏëÔÚÄÚ´æÖн¨Á¢Ò»Ð©±íʾÁ÷Ë®ÏßµÄÊý¾Ý½á¹¹¡­¡­ÕâÕýÊÇÎÒÃÇ¶Ô monad µÄ¡°µÍЧ¡±Ê¹ÓÃËù²úÉúµÄ½á¹û£¡

ΪÁËʹÆäÓÐÓã¬ÎÒÃÇÐèÒª»ù±¾²Ù×÷£¨±ÈÈç fetch£©À´Îª¾²Ì¬·ÖÎöÌṩһЩÐÅÏ¢£¨±ÈÈç±êÇ©£©¡£OCaml µÄ let Ó﷨ûÓÐΪ±êÇ©ÌṩÃ÷ÏÔµÄλÖ㬵«ÊÇÎÒÄܹ»¶¨ÒåÒ»¸öÔËËã·û£¨let**£©£¬¸ÃÔËËã·û·µ»ØÒ»¸ö½ÓÊÜ label ²ÎÊýµÄº¯Êý¡£Ëü¿ÉÓÃÓÚÉú³ÉÈçÏ»ù±¾²Ù×÷£º

let fetch commit =
"fetch" |>
let** commit = commit in
(* (standard monadic implementation of fetch goes here) *)

Òò´Ë£¬fetch ½ÓÊÜÒ»¸öÌá½»µÄ³Ðŵ£¬¶ÔËüÖ´ÐÐÒ»¸öµ¥×Ö½Ú°ó¶¨ÒԵȴýʵ¼ÊµÄÌá½»£¬È»ºóÏñÒÔǰһÑù¼ÌÐø£¬µ«Ëü½«°ó¶¨±ê¼ÇΪһ¸ö fetch ²Ù×÷¡£Èç¹û fetch °üº¬¶à¸ö²ÎÊý£¬Ôò¿ÉÒÔʹÓà and* ²¢ÐеȴýËùÓвÎÊý¡£

ÀíÂÛÉÏ£¬let**In fetch µÄÖ÷Ìå¿ÉÒÔ°üº¬½øÒ»²½µÄ°ó¶¨¡£Èç¹ûÄÇÑùµÄ»°£¬ÎÒÃÇÔÚÒ»¿ªÊ¼¾ÍÎÞ·¨·ÖÎöÕû¸ö¹ÜµÀ¡£µ«ÊÇ£¬Ö»ÒªÔ­ÓïÔÚ¿ªÊ¼Ê±µÈ´ýËùÓÐÊäÈ룬²¢ÇÒ²»ÔÚÄÚ²¿½øÐÐÈκΰ󶨣¬ÎÒÃǾͿÉÒÔ¾²Ì¬µØ·¢ÏÖÕû¸ö¹ÜµÀ¡£

ÎÒÃÇ¿ÉÒÔÑ¡ÔñÊÇ·ñ½«ÕâЩ°ó¶¨²Ù×÷¹«¿ª¸øÓ¦ÓóÌÐò´úÂë¡£Èç¹û let*£¨»ò let**£©±»¹«¿ª£¬ÄÇôӦÓóÌÐò¾Í¿ÉÒÔʹÓà monad µÄËùÓбí´ïÄÜÁ¦£¬µ«ÊÇÔÚijЩ³Ðŵ½â¾ö֮ǰ£¬ÎÒÃǽ«ÎÞ·¨ÏÔʾÕû¸ö¹ÜµÀ¡£Èç¹ûÎÒÃÇÒþ²ØËüÃÇ£¬ÄÇôӦÓóÌÐòÖ»ÄÜÉú³É¾²Ì¬¹ÜµÀ¡£

µ½Ä¿Ç°ÎªÖ¹£¬Îҵķ½·¨ÊÇʹÓà let* ×÷ΪÌÓÉú²Õ¿Ú£¬ÕâÑù¾Í¿ÉÒÔ½¨ÔìÈκÎËùÐèµÄ¹ÜµÀ£¬µ«ÎÒºóÀ´ÓøüרҵµÄ²Ù×÷À´´úÌæËüµÄÈκÎÓÃ;¡£ÀýÈ磬ÎÒÌí¼ÓÁË£º

val list_map : ('a t -> 'b t) -> 'a list t -> 'b list t

Õ⽫´¦ÀíÔËÐÐʱ²ÅÖªµÀµÄÁбíÖеÄÿ¸öÏȻ¶ø£¬ÎÒÃÇÈÔÈ»¿ÉÒÔ¾²Ì¬µØÖªµÀÎÒÃǽ«Ó¦ÓÃÓÚÿ¸öÏîµÄ¹ÜµÀ£¬¼´Ê¹ÎÒÃDz»ÖªµÀÏî±¾ÉíÊÇʲô¡£list_map ±¾À´¿ÉÒÔʹÓà let* ʵÏÖ£¬µ«ÕâÑùÎÒÃǾÍÎÞ·¨¾²Ì¬µØ¿´µ½¹ÜµÀ¡£

ÏÂÃæÊÇÁíÍâÁ½¸öʹÓà dart ·½·¨µÄʾÀý£º

let example2 commit =
let src = fetch commit in
let base = docker_pull "ocaml/opam2" in
let build ocaml_version =
let dockerfile =
let+ base = base in
make_dockerfile ~base ~ocaml_version in
let image = build ~dockerfile src ~label:ocaml_version in
test image
in
all [
build "4.07";
build "4.08"
]

ÓëÔ­À´Ïà±È£¬ÎÒÃÇÓÐÒ»¸ö all À´ºÏ²¢½á¹û£¬²¢ÇÒÔÚ¼ÆËã dockerfile ʱÓÐÒ»¸ö¶îÍâµÄ let+base=base¡£let+ Ö»ÊÇ map µÄÁíÒ»ÖÖÓï·¨£¬ÔÚÕâÀïʹÓã¬ÒòΪÎÒÑ¡Ôñ²»¸ü¸Ä make_dockerfile µÄÇ©Ãû¡£»òÕߣ¬ÎÒÃÇ¿ÉÒÔÈÃÄãµÄ dockerfile ½ÓÊÜÒ»¸ö»ù±¾Í¼ÏñµÄ³Ðŵ£¬²¢ÔÚÀïÃæ×öµØÍ¼¡£ÒòΪ map ÐèÒªÒ»¸ö´¿ÊµÌ壨make_dockerfile Ö»Éú³ÉÒ»¸ö×Ö·û´®£»Ã»ÓгÐŵ»ò´íÎ󣩣¬ËùÒÔËü²»ÐèÒªÔÚͼ±íÉÏÓÐ×Ô¼ºµÄ¿ò£¬²¢ÇÒÎÒÃDz»»áÒòΪÔÊÐíʹÓÃËü¶ø¶ªÊ§Èκζ«Î÷¡£

let example3 commit =
let src = fetch commit in
let image = build src in
let ok = test image in
let revdeps = get_revdeps src in
gate revdeps ~on:ok |>
list_iter ~pp:Fmt.string example1

ÕâÏÔʾÁËÁíÒ»¸ö×Ô¶¨Òå²Ù×÷£ºgate revdeps~on:ok ÊÇÒ»¸ö³Ðŵ£¬Ö»ÓÐÔÚ revdeps ºÍ ok ¶¼½â¾öºó²ÅÄܽâ¾ö¡£Õ⽫×èÖ¹ËüÔÚ¿â×Ô¼ºµÄ²âÊÔͨ¹ý֮ǰ²âÊÔ¿âµÄ revdeps£¬¼´Ê¹Èç¹ûÎÒÃÇÏ£ÍûËü¿ÉÒÔ²¢ÐеØÕâÑù×ö¡£¶ø¶ÔÓÚ monad£¬ÎÒÃDZØÐëÔÚÐèÒªµÄµØ·½ÏÔʽµØÆôÓò¢·¢£¨Ê¹ÓÃºÍ *£©£¬¶ø¶ÔÓÚ dart£¬ÎÒÃDZØÐëÔÚ²»ÐèÒªµÄµØ·½ÏÔʽµØ½ûÓò¢·¢£¨Ê¹Óà gate£©¡£

ÎÒ»¹Ìí¼ÓÁËÒ»¸ö list-iter ±ãÀûº¯Êý£¬²¢ÎªËüÌṩÁËÒ»¸öƯÁÁµÄ printer ²ÎÊý£¬ÕâÑùÒ»µ©ÖªµÀÁбíÊäÈ룬ÎÒÃǾͿÉÒÔÔÚͼ±íÖбê¼Ç°¸Àý¡£

×îºó£¬ËäÈ»ÎÒ˵¹ý²»ÄÜÔÚÔ­ÓïÖÐʹÓà let*£¬µ«ÈÔÈ»¿ÉÒÔʹÓÃÆäËûһЩ monad£¨Ëü²»»áÉú³Éͼ£©¡£Êµ¼ÊÉÏ£¬ÔÚʵ¼ÊϵͳÖУ¬ÎÒ¶ÔÔ­ÓïʹÓÃÁËÒ»¸öµ¥¶ÀµÄ let>²Ù×÷·û¡£Õâ¾ÍÒªÇóÖ÷ÌåʹÓõײã promise ¿âÌṩµÄ·ÇͼÉú³É³Ðŵ£¬Òò´Ë²»ÄÜÔÚÔ­ÓïµÄÖ÷ÌåÖÐʹÓà let*£¨»ò let>£©¡£

ºÍ Arrow ½øÐбȽÏ

¸ø¶¨Ò»¸ö¡°dart¡±£¬Äú¿ÉÒÔͨ¹ý¶¨ÒåÀýÈç¡£

type ('a, 'b) arrow = 'a promise -> 'b promise

 

ÄÇô arr ¾ÍÊÇ map£¬f>>>g ¾ÍÊÇÓÐȤµÄ x->g£¨fx£©¡£µÚÒ»¸öÒ²¿ÉÒÔºÜÈÝÒ׵ض¨Ò壬¼ÙÉèÄãÓÐijÖÖº¯ÊýÀ´²¢ÐеØ×öÁ½¼þÊ£¨±ÈÈçÉÏÃæµÄºÍÎÒÃǵģ©¡£

Òò´Ë£¬dart API£¨¼´Ê¹ÓÐ let*hidden£©ÈÔÈ»×ãÒÔ±íʾÈκοÉÒÔʹÓüýÍ· API ±íʾµÄ¹ÜµÀ¡£

Haskell ¼ýÍ·½Ì³Ì ʹÓÃÒ»¸ö¼ýÍ·ÊÇÓÐ״̬º¯ÊýµÄʾÀý¡£ÀýÈ磬ÓÐÒ»¸ö total ¼ýÍ·£¬Ëü·µ»ØËüµÄÊäÈëºÍÒÔǰµ÷ÓÃËüµÄÿ¸öÊäÈëµÄ×ܺ͡£e¡¢ g. ÓÃÊäÈë 1 2 3 µ÷ÓÃÈý´Î£¬²úÉúÊä³ö 1 3 6¡£¶ÔÊäÈëÐòÁÐÔËÐйܵÀ½«·µ»ØÊä³öÐòÁС£

±¾½Ì³ÌʹÓà total ¶¨Òå mean1 º¯Êý£¬ÈçÏÂËùʾ£º

mean1 = (total &&& (arr (const 1) >>> total)) >>> arr (uncurry (/))

Òò´Ë£¬´Ë¹ÜµÀ¸´ÖÆÃ¿¸öÊäÈë±àºÅ£¬½«µÚ¶þ¸ö±àºÅÌæ»»Îª 1£¬½«Á½¸öÁ÷Ïà¼Ó£¬È»ºóÓÃÆä±ÈÂÊÌæ»»Ã¿¶Ô¡£Ã¿´Î½«ÁíÒ»¸öÊý×Ö·ÅÈë¹ÜµÀʱ£¬¶¼»áµÃµ½Æù½ñΪֹÊäÈëµÄËùÓÐÖµµÄƽ¾ùÖµ¡£

ʹÓà dart ÑùʽµÄµÈЧ´úÂëÊÇ£¨OCaml ʹÓà /¡£¶ÔÓÚ¸¡µã³ý·¨£©£º

let mean values =
let t = total values in
let n = total (const 1.0) in
map (uncurry (/.)) (pair t n)

Õâ¶ÔÎÒÀ´Ëµ¸üÈÝÒ×Àí½â¡£Í¨¹ý¶¨Òå±ê×¼ÔËËã·û let+£¨¶ÔÓÚ map£©ºÍ +£¨¶ÔÓÚ pair£©£¬ÎÒÃÇ¿ÉÒÔÉÔ΢¼ò»¯´úÂ룺

let (let+) x f = map f x
let (and+) = pair
let mean values =
let+ t = total values
and+ n = total (const 1.0) in
t /. n

ÎÞÂÛÈçºÎ£¬Õâ²»ÊÇÒ»¸öºÜºÃµÄ¼ýͷʾÀý£¬ÒòΪÎÒÃDz»Ê¹ÓÃÒ»¸ö״̬º¯ÊýµÄÊä³ö×÷ΪÁíÒ»¸ö״̬º¯ÊýµÄÊäÈ룬ËùÒÔÕâʵ¼ÊÉÏÖ»ÊÇÒ»¸ö¼òµ¥µÄ applicative.

²»¹ý£¬ÎÒÃÇ¿ÉÒÔºÜÈÝÒ×µØÓÃÁíÒ»¸öÓÐ״̬º¯ÊýÀ©Õ¹Ê¾Àý¹ÜµÀ£¬Ò²Ðí¿ÉÒÔÌí¼ÓһЩƽ»¬´¦Àí¡£Õâ¿´ÆðÀ´Ïñ¼ýÍ··ûºÅÖÐµÄ mean1>>>ƽ»¬£¬Ê¡µÀ·ûºÅÖеÄÖµ|>ƽ¾ùÖµ|>ƽ»¬£¨»òƽ»¬£¨Æ½¾ùÖµ£©£©¡£

×¢Ò⣺Haskell »¹ÓÐÒ»¸ö Arrows Óï·¨À©Õ¹£¬ËüÔÊÐí Haskell ´úÂë±àдΪ£º

mean2 = proc value -> do
t <- total -< value
n <- total -< 1
returnA -< t / n

Õâ¸üÏñÊÇ·ÉïÚ·ûºÅ¡£

¸ü¶àʾÀý

ÎÒÔÚ ocurrent/ocurrent ÉϽ¨Á¢ÁËÒ»¸öʹÓÃÕâЩ˼ÏëµÄÉÔ΢À©Õ¹°æ±¾µÄ¿â¡£×ÓĿ¼ lib_term ÊÇÓëÕâÆª²©¿ÍÎÄÕÂÏà¹ØµÄ²¿·Ö£¬ÔÚ TERM ÖÐÃèÊöÁ˸÷ÖÖ×éºÏ´Ê¡£

ÆäËûĿ¼´¦Àí¸ü¾ßÌåµÄϸ½Ú£¬ÀýÈçÓë Lwt promise ¿âµÄ¼¯³É£¬Ìṩ¹ÜÀí web UI »ò Cap¡¯n Proto RPC ½Ó¿Ú£¬ÒÔ¼°´øÓÐÓÃÓÚʹÓà Git¡¢GitHub¡¢Docker ºÍ Slack µÄÔ­ÓïµÄ²å¼þ¡£

OCaml Docker »ù´¡¾µÏñ¹¹½¨

ocurrent/docker-base-images °üº¬Ò»¸ö¹ÜµÀ£¬ÓÃÓÚΪ¸÷ÖÖ Linux ·¢Ðа桢CPU ¼Ü¹¹¡¢OCaml ±àÒëÆ÷°æ±¾ºÍÅäÖÃÑ¡Ïî¹¹½¨ OCaml µÄ Docker »ù±¾Ó³Ïñ¡£ÀýÈ磬ҪÔÚ Debian 10 ÉϲâÊÔ OCAML4.09£¬¿ÉÒÔÖ´ÐÐÒÔϲÙ×÷£º

$ docker run --rm -it ocurrent/opam:debian-10-ocaml-4.09
:~$ ocamlopt --version
4.09.0
:~$ opam depext -i utop
[...]
:~$ utop
----+--------+------------------
| Welcome to utop version 2.4.2 (using OCaml version 4.09.0)! |
+---------------------------+
Type #utop_help for help about using utop.
-( 11:50:06 )-< command 0 > -------------{ counter: 0 }-
utop #

ÒÔÏÂÊǹܵÀµÄÍâ¹Û£¨µ¥»÷¿É²é¿´ÍêÕû³ß´ç£©

ËüÿÖÜÌáÈ¡ opam ´æ´¢¿âµÄ×îРGit Ìá½»£¬È»ºóΪÿ¸ö·¢Ðа湹½¨°üº¬¸ÃÄÚÈݵĻù±¾Ó³ÏñºÍ opam °ü¹ÜÀíÆ÷£¬È»ºóΪÿ¸öÊÜÖ§³ÖµÄ±àÒëÆ÷±äÌå¹¹½¨Ò»¸öÓ³Ïñ¡£Ðí¶àͼƬÊǽ¨Á¢ÔÚ¶à¸ö¼Ü¹¹£¨amd64¡¢arm32¡¢arm64 ºÍ ppc64£©Éϵ쬲¢±»ÍƵ½ Docker Hub µÄÒ»¸öÔÝ´æÇø¡£È»ºó£¬¹ÜµÀ½«ËùÓÐÉ¢ÁÐ×éºÏÆðÀ´£¬½«Ò»¸ö¶à¼Ü¹¹Çåµ¥ÍÆË͵½ Docker Hub¡£»¹ÓÐһЩ±ðÃû£¨ÀýÈ磬debian ±íʾ debian-10-ocaml-4.09£©¡£×îºó£¬Èç¹ûÓÐÈκÎÎÊÌ⣬Ôò¹ÜµÀ»á½«´íÎó·¢Ë͵½ËɳÚͨµÀ¡£

Äú¿ÉÄÜÏëÖªµÀ£¬ÎÒÃÇÊÇ·ñÕæµÄÐèÒªÒ»¸ö¹ÜµÀÀ´ÊµÏÖÕâÒ»µã£¬¶ø²»ÊÇ´Ó cron ×÷ÒµÔËÐÐÒ»¸ö¼òµ¥µÄ½Å±¾¡£µ«ÊÇÓµÓÐÒ»¸ö¹ÜµÀ¿ÉÒÔÈÃÎÒÃÇÔÚÔËÐÐËü֮ǰ¿´µ½¹ÜµÀ½«Òª×öʲô£¬¹Û²ì¹ÜµÀµÄ½ø¶È£¬µ¥¶ÀÖØÐÂÆô¶¯Ê§°ÜµÄ×÷Òµ£¬µÈµÈ£¬¼¸ºõÓëÎÒÃDZàдµÄ´úÂëÏàͬ¡£

Èç¹ûÄãÏë¿´Íê³ÉµÄÁ÷Ë®Ïߣ¬¿ÉÒÔÔĶÁ pipeline.ml¡£

OCaml CI

ocurrent/ocaml-ci ÊÇÒ»¸öÓÃÓÚ²âÊÔ OCaml ÏîÄ¿µÄ£¨ÊµÑéÐԵģ©GitHub Ó¦ÓóÌÐò¡£¹ÜµÀ»ñȡӦÓóÌÐòµÄ°²×°ÁÐ±í£¬»ñȡÿ¸ö°²×°µÄÒÑÅäÖô洢¿â£¬»ñȡÿ¸ö´æ´¢¿âµÄ·ÖÖ§ºÍ PRs£¬È»ºóÕë¶Ô¶à¸ö Linux ·¢ÐаæºÍ OCaml ±àÒëÆ÷°æ±¾²âÊÔÿ¸ö´æ´¢¿âµÄÍ·²¿¡£Èç¹ûÏîĿʹÓà ocamlformat£¬Ëü»¹»á¼ì²éÌá½»µÄ¸ñʽÊÇ·ñÓë ocamlformat µÄ¸ñʽÍêÈ«Ïàͬ¡£

½á¹û×÷ΪÌύ״̬±»Íƻص½ GitHub£¬²¢¼Ç¼ÔÚ web ºÍ tty ui µÄ±¾µØË÷ÒýÖС£ÕâÀïÓкܶàºìÉ«£¬Ö÷ÒªÊÇÒòΪÈç¹ûÒ»¸öÏîÄ¿²»Ö§³ÖÌØ¶¨°æ±¾µÄ OCaml£¬ÄÇô¹¹½¨»á±»±ê¼ÇΪʧ°Ü£¬²¢ÔڹܵÀÖÐÏÔʾΪºìÉ«£¬¾¡¹ÜÔÚÉú³É GitHub ״̬±¨¸æÊ±»á¹ýÂ˵ôÕâЩʧ°Ü¡£ÎÒÃÇ¿ÉÄÜÐèÒªÒ»¸öеÄÑÕÉ«Ìø¹ý½×¶Î¡£

½áÂÛ

±àд CI/CD ¹ÜµÀºÜ·½±ã£¬¾ÍºÃÏñËüÃÇÊÇÒ»´ÎÁ¬ÐøÔËÐÐÕâЩ²½Ö貢ʼÖճɹ¦µÄµ¥µã½Å±¾Ò»Ñù£¬È»ºóÖ»ÒªÉÔ×÷¸ü¸Ä£¬¹ÜµÀ¾Í»áÔÚÊäÈë¸ü¸ÄʱÔËÐÐÕâЩ²½Ö裬ͬʱÌṩÈÕÖ¾¼Ç¼¡¢´íÎ󱨸桢ȡÏûºÍÖØ½¨Ö§³Ö¡£

ʹÓà monad ¿ÉÒÔºÜÈÝÒ׵ؽ«ÈκγÌÐòת»»Îª¾ßÓÐÕâÐ©ÌØÐԵijÌÐò£¬µ«ÊÇ£¬Óë³£¹æ³ÌÐòÒ»Ñù£¬ÔÚÔËÐÐijЩÊý¾Ý֮ǰ£¬ÎÒÃDz»ÖªµÀ¸Ã³ÌÐò½«ÈçºÎ´¦ÀíÕâЩÊý¾Ý¡£ÌرðÊÇ£¬ÎÒÃÇÖ»ÄÜ×Ô¶¯Éú³ÉÏÔʾÒѾ­¿ªÊ¼µÄ²½ÖèµÄͼ±í¡£

´«Í³µÄ¾²Ì¬·ÖÎö·½·¨ÊÇʹÓüýÍ·¡£Õâ±Èµ¥Ôª¸ñÉÔ΢ÓÐÏÞ£¬ÒòΪÁ÷Ë®ÏߵĽṹ²»Äܸù¾ÝÊäÈëÊý¾Ý¶ø¸Ä±ä£¬¾¡¹ÜÎÒÃÇ¿ÉÒÔÔö¼ÓÓÐÏÞµÄÁé»îÐÔ£¬ÀýÈç¿ÉÑ¡µÄ²½Öè»òÁ½¸ö·ÖÖ§Ö®¼äµÄÑ¡Ôñ¡£µ«ÊÇ£¬Ê¹ÓüýÍ··ûºÅ±àд¹ÜµÀÊǺÜÀ§Äѵģ¬ÒòΪÎÒÃDZØÐëʹÓÃÎÞµãÑùʽ£¨Ã»ÓбäÁ¿£©±à³Ì¡£

ͨ¹ýÒÔÒ»ÖÖ²»Ñ°³£µÄ·½Ê½Ê¹Óà monad£¨ÕâÀï³ÆÎª¡°dart¡±£©£¬ÎÒÃÇ¿ÉÒÔ»ñµÃ¾²Ì¬·ÖÎöµÄÏàͬºÃ´¦¡£ÎÒÃǵĺ¯Êý²»ÊǽÓÊÜ´¿Öµ²¢·µ»Ø°ü×°ÖµµÄº¯Êý£¬¶øÊǽÓÊܲ¢·µ»Ø°ü×°Öµ¡£Õâµ¼ÖÂÓï·¨¿´ÆðÀ´ÓëÆÕͨ±à³ÌÏàͬ£¬µ«ÔÊÐí¾²Ì¬·ÖÎö£¨´ú¼ÛÊÇÎÞ·¨Ö±½Ó²Ù×÷°ü×°µÄÖµ£©¡£

Èç¹ûÎÒÃÇÒþ²Ø£¨»ò²»Ê¹Óã©monad µÄ let*£¨bind£©º¯Êý£¬ÄÇôÎÒÃÇ´´½¨µÄ¹ÜµÀ×ÜÊÇ¿ÉÒÔ¾²Ì¬µØÈ·¶¨µÄ¡£Èç¹ûÎÒÃÇʹÓð󶨣¬ÄÇô¹ÜµÀÖлáÓÐËæ×ŹܵÀÔËÐжøÀ©Õ¹µ½¸ü¶à¹ÜµÀ½×¶ÎµÄ¿×¡£

»ù±¾²½Öè¿ÉÒÔͨ¹ýʹÓõ¥¸ö¡°±êÇ©°ó¶¨¡±´´½¨£¬ÆäÖбêǩΪԭ×Ó×é¼þÌṩ¾²Ì¬·ÖÎö¡£

ÎÒÒÔǰ´Óδ¼û¹ýʹÓùýÕâÖÖģʽ£¨»òÕßÔÚ arrow ÎĵµÖÐÌáµ½¹ý£©£¬ËüËÆºõÌṩÁËÓë arrow ÍêÈ«ÏàͬµÄºÃ´¦£¬¶øÇÒÄѶÈҪСµÃ¶à¡£Èç¹ûÕâ¸öÃû×ÖÊÇÕæµÄ£¬¸æËßÎÒ£¡

ÕâÏ×÷ÓÉ OCaml ʵÑéÊÒ×ÊÖú¡£

   
2081 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

ΪʲôҪ×ö³ÖÐø²¿Êð£¿
ÆÊÎö¡°³ÖÐø½»¸¶¡±£ºÎå¸öºËÐÄʵ¼ù
¼¯³ÉÓë¹¹½¨Ö¸ÄÏ
³ÖÐø¼¯³É¹¤¾ßµÄÑ¡Ôñ-×°ÔØ
Ïà¹ØÎĵµ

³ÖÐø¼¯³É½éÉÜ
ʹÓÃHudson³ÖÐø¼¯³É
³ÖÐø¼¯³ÉÖ®-ÒÀÀµ¹ÜÀí
IPD¼¯³É²úÆ·¿ª·¢¹ÜÀí
Ïà¹Ø¿Î³Ì

ÅäÖùÜÀí¡¢ÈÕ¹¹½¨Óë³ÖÐø¼¯³É
Èí¼þ¼Ü¹¹Éè¼Æ·½·¨¡¢°¸ÀýÓëʵ¼ù
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
»ùÓÚAndroidµÄµ¥Ôª¡¢ÐÔÄܲâÊÔ