読者です 読者をやめる 読者になる 読者になる

non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

OCaml(OpenGL)で「プログラムでシダを描画する」を通して学んだことのまとめ

おはようございます。奥さんが大阪に出張のため、息子たちと実家で生活しているkjunichiです。なぜか長男がいつもはしない夜泣きを久しぶりにしました。
 

はじめに

俺が、これ先に知ってれば、何週間もかからずさくっと書けたのに、という事項を ピックアップ。

筆者は、関数型言語の存在自体は知ってはいるが、今回OCamlで悪戦苦闘する以前には触れたことが ほとんどない。

おい、If文すら俺には理解が難しかった。

OCamlのコードは;や;;を省略できる。その為、コピペでつくろうとするとハマる。

基本

文の終わりは;; 複数処理が続くようなときは;

If文の基本形は

if 条件 then
begin
hoge;
foo;
end
else
begin
foo;
koo;
end
;;

ただし、「;;」を付けてよいのは、コードの一番外側で書いている時。

forループもif文が理解でてりゃ、たぶん問題ない(俺調べ)

破壊的代入しなきゃ凡人にはコード書けない件

let a = Array.make 3 0;;
for i = 0 to 3 - 1 do
 print_int a.(i);
 print_endline "";
done;;

print_endline "< --- >";;

(* 配列なら破壊的代入が簡単 *)
a.(1) <- 3;;
a.(0) <- (-3);;

for i = 0 to 3 - 1 do
 print_int a.(i);
 print_endline "";
done;;

OCamlで多次元配列のサンプルが2次元までな件

日本語で探しても、簡単に配列を入れ子にすりゃいいんだと、お利口さん向けの解説しかない! しかも、Array.makeを使ったコードは見当たらない状態。。

そんな中、低スキルの俺は

let image_width = 100;;
let image_height = 100;;

let buf = Array.make_matrix image_width image_height 0.0;;
let imgBuf = Array.make 3 buf;;

print_float imgBuf.(0).(50).(10);;
print_endline "<- imgBuf.(0).(50).(10)";;
print_float imgBuf.(1).(50).(10);;
print_endline "<- imgBuf.(1).(50).(10)";;

imgBuf.(1).(50).(10) <- 0.5;;

print_float imgBuf.(0).(50).(10);;
print_endline "<- imgBuf.(0).(50).(10)";;
print_float imgBuf.(1).(50).(10);;
print_endline "<- imgBuf.(1).(50).(10)";;

が、これだと

0.<- imgBuf.(0).(50).(10)
0.<- imgBuf.(1).(50).(10)
0.5<- imgBuf.(0).(50).(10)
0.5<- imgBuf.(1).(50).(10)

配列の扱いは関数型といえども、メモリの制約なのか、C言語的思考が必要だった

ビット演算とか今日日メモリ有り余ってるので、めんどい、RGBそれぞれで2次元バッファを用意して、 3次元配列にしたい場合、以下のようにやり過ごせた

let imageBuf p n m init =
    let result = Array.make p (Array.make n (Array.make m init)) in
        for j = 1 to p - 1 do
            result.(j) <- Array.make n (Array.make m init);
            for i = 1 to n - 1 do
                result.(j).(i) <- Array.make m init
            done;
        done;
        result;;

let buf = imageBuf 3 200 200 0.0;;

Link

関連記事