2016年5月23日月曜日

DoNe2

  • 動いてると思うけど書き殴りだから細かいことは気にしないでね
  • 単に機能が増えて面倒になっただけで、状態渡しのしかたは前回と同じ。
  • メインループではなくハンドラでOCaml部分の状態渡しをしてるので、「メインループを書き直してるからスケールしない」というのとは少し違う。
  • (状態渡しや関数型云々とは無関係に)やっぱりDOMかつ静的型だとちょっと長くなるね(定数倍ファクターなのでスケール云々とも無関係)。
  • 俺もOCamlの勉強になったけど、「できない」と断言されたことをすぐにやって見せたんだから(それも3回。しかも他人に「課題」とか言った本人は1年がかり、かつ関数型ではなく全くの命令型。決して認めないようだが。)、もうつきあう義理はないよね。
  • 「中国製不正アクセス機器を使って誹謗中傷してる犯罪者集団」みたいな妄想はマジ勘弁。それを釣りで煽ってる奴ら(単独?)もな。

DoNe2

List#1
    module H = Dom_html
    let g x = Js.Opt.get x (fun () -> assert false)
    let o x = Js.Opt.return x
    let s = Js.string
    let i = string_of_int
    
    type ('a, 'b) state =
        (* just to omit explicit annotation of complex types by (ab)using "polymorphism" *)
        { itemss : 'a list list; cur : int; selects : 'b }
    
    let _ = H.window##onload <- H.handler (fun _ ->
      Firebug.console##debug(s "DoNe2 starting");
      let d = H.document in
      let tm = g (d##getElementById (s "todo2_time")) in
      ignore
        (H.window##setInterval
           (Js.wrap_callback (fun _ ->
             tm##textContent <- o (jsnew Js.date_now ()##toString ())),
            100.));
    
      let nu = g (H.CoerceTo.input (g (d##getElementById (s "todo2_new")))) in
      let selects = g (d##getElementById (s "todo2_selects")) in
      let select1 = g (H.CoerceTo.input (g (d##getElementById (s "todo2_select1")))) in
      let selected = g (d##getElementById (s "todo2_selected")) in
      let input = g (H.CoerceTo.input (g (d##getElementById (s "todo2_input")))) in
      let go = g (H.CoerceTo.input (g (d##getElementById (s "todo2_go")))) in
      let ul = g (H.CoerceTo.ul (g (d##getElementById (s "todo2_ul")))) in
    
      (* ここまでDOMの準備。ここから本体 *)
    
      let rec generate_handlers st =
        let rec handle_sub _ =
          let v = input##value in
          let rec add_v pos = function (* 補助関数 *)
            | [] -> assert false
            | items :: itemss when pos = 1 -> (items @ [v]) :: itemss
            | items :: itemss -> items :: add_v (pos - 1) itemss in
          let new_itemss = add_v st.cur st.itemss in
          Firebug.console##debug(s ("DoNe2 adding to List#" ^ i st.cur ^ ": " ^ Js.to_string v));
          input##value <- s "";
          configure_ui { st with itemss = new_itemss };
          Js._false
        and handle_nu _ =
          let new_list = H.createInput ~_type:(s "submit") d in
          let new_selects = st.selects @ [new_list] in
          let new_itemss = st.itemss @ [[]] in
          let new_cur = List.length new_selects in
          new_list##value <- s ("List#" ^ i new_cur);
          Dom.appendChild selects new_list;
          configure_ui { (* st with *) itemss = new_itemss; cur = new_cur; selects = new_selects };
          Js._false
        and handle_select new_cur _ =
          configure_ui { st with cur = new_cur };
          Js._false
        in
        (handle_sub, handle_nu, handle_select)
    
      and configure_ui st =
        selected##textContent <- o (s ("List#" ^ i st.cur));
        go##value <- s ("NewDoNe#" ^ i (1 + List.length (List.nth st.itemss (st.cur - 1))));
    
        let rec rm_all_child p = (* 補助関数 *)
          Js.Opt.case (p##firstChild) (fun () -> ())
            (fun c ->
              ignore (p##removeChild(c));
              rm_all_child p) in
        rm_all_child ul;
        List.iter
          (fun item ->
            let li = H.createLi d in
            li##textContent <- o item;
            Dom.appendChild ul li)
          (List.nth st.itemss (st.cur - 1));
    
        let (handle_sub, handle_nu, handle_select) = generate_handlers st in
        go##onclick <- H.handler handle_sub;
        nu##onclick <- H.handler handle_nu;
        List.iteri
          (fun n selected ->
            selected##onclick <- H.handler (handle_select (1 + n)))
          st.selects
      in
      configure_ui { itemss = [[]]; cur = 1; selects = [select1] };
      Js._false)
    

    0 件のコメント:

    コメントを投稿