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

牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

すごE本を読んでみたメモ -- 第4章

書籍『すごいErlangゆかいに学ぼう!/Learn You Some Erlang for great good! 』まとめ

第4章 型(あるいはそれを欠いています)

4.1 動的で強い型付け

  • Erlang は強い型付き言語

4.2 型変換

1> erlang:list_to_integer("54").
54
2> erlang:integer_to_list(54).
"54"
3> erlang:list_to_integer("54.32").
** exception error: bad argument
in function list_to_integer/1 called as list_to_integer("54.32") 4> erlang:list_to_float("54.32").
54.32
5> erlang:atom_to_list(true).
"true"
6> erlang:list_to_binary("hi there").
<<"hi there">>
7> erlang:binary_to_list(<<"hi there">>).
"hi there"

変換用関数一覧

  • atom_to_binary/2
  • atom_to_list/1
  • binary_to_atom/2
  • binary_to_existing_atom/2
  • binary_to_list/1
  • binary_to_term/1
  • binary_to_term/2
  • bitstring_to_list/1
  • float_to_list/1
  • fun_to_list/1
  • integer_to_list/1
  • integer_to_list/2
  • iolist_to_atom/1
  • iolist_to_binary/1
  • list_to_atom/1
  • list_to_binary/1
  • list_to_bitstring/1
  • list_to_existing_atom/1
  • list_to_float/1
  • list_to_integer/2
  • list_to_pid/1
  • list_to_tuple/1
  • pid_to_list/1
  • port_to_list/1
  • ref_to_list/1
  • term_to_binary/1
  • term_to_binary/2
  • tuple_to_list/1

4.3 データ型を守るために

型テスト BIF

  • is_atom/1
  • is_binary/1
  • is_bitstring/1
  • is_boolean/1
  • is_builtin/3
  • is_float/1
  • is_function/1
  • is_function/2
  • is_integer/1
  • is_list/1
  • is_number/1
  • is_pid/1
  • is_port/1
  • is_record/2
  • is_record/3
  • is_reference/1
  • is_tuple/1

以下2つのコードは同じだが Erlang では後者が好まれる。

my_function(Exp) ->
    case type_of(Exp) of
        binary -> Expression1;
        list -> Expression2
    end.
my_function(Exp) when is_binary(Exp) -> Expression1;
my_function(Exp) when is_list(Exp) -> Expression2.

4.4 型ジャンキーのために

第 30 章では簡単に Erlang で 静的型解析を行うツールである Dialyzer を紹介し、独 自の型を定義してより安全にコードを書く方法を紹介 します。

flake8 の設定を変更するメモ

(python2.7.13, flake8v3.2.1)

  • ~/.flake8 にファイルを作って設定を書く
[flake8]
max-line-length = 120

参考

Configuring Flake8 — flake8 3.3.0.dev0 documentation

網戸を自分で取り替えてみたメモ

必要なもの

材料

道具

料金

  • Amazonだと材料と道具で
    • 1186+5712+3772+204+366 = 3,652円
  • ホームセンターだともうちょい安い
  • ちなみに張り替えサービスに頼むと1枚3,000円〜くらい?
    • うちの場合だと 4900*2+2900 = 12,700円?
    • もしくは 2900*5 = 14,500円?
    • どちらにしても結構お高くなるのね。。。

作業時間

  • 網戸の数:2面x2 + 1面
    • 1面のやつの存在忘れててゴム足りなくなった...
  • 問題が発生して2~3時間かかった
    • クリップ2個しかかってなかったので買いに行った
    • 戸の立て付けが悪かったりで取り外し・付けに手間取った

結果

  • うーん、イマイチ綺麗に貼れなかったような気がする。
  • 3〜4回やれば綺麗やれそうかも。(次やる時は忘れてそう...)
  • 正直超面倒臭い
    • お安くやってもらえるならやってほしいけど高くなりそう。
  • 綺麗になったしまあいいか
    • (10年以上取り替えてなかったし)

参考

すごE本を読んでみたメモ -- 第3章

書籍『すごいErlangゆかいに学ぼう!/Learn You Some Erlang for great good! 』まとめ

第3章 関数の構文

3.1 パターンマッチ

function(Args)
    if X then
〔式〕
else if Y then
〔式〕 else〔式〕

ではなく

function(X) ->
    〔式〕;
function(Y) ->
    〔式〕;
function(_) ->
    〔式〕.

と書く

  • それぞれの function 宣言が 関数節
  • 関数節は ; で区切られ、 関数宣言 でまとめられる。

ちょっと凝ったパターンマッチ

-module(functions).
-compile(export_all). % Replace with -export() later, for sanity's sake!

head([H|_]) -> H.
second([_,X|_]) -> X.
1> c(functions).
{ok, functions}
2> functions:head([1,2,3,4]).
1
3> functions:second([1,2,3,4]).
2

束縛する変数

  • 束縛されている変数に値を与えようとすると、新しい値が束縛されている値と同じでない限り 、エラーが発生します。
    valid_time({Date = {Y,M,D}, Time = {H,Min,S}}) ->
        io:format("The Date tuple (~p) says today is: ~p/~p/~p,~n",[Date,Y,M,D]),
        io:format("The time tuple (~p) indicates: ~p:~p:~p.~n", [Time,H,Min,S]);
    valid_time(_) ->
        io:format("Stop feeding me wrong data!~n").
4> c(functions).
{ok, functions}
5> functions:valid_time({{2013,12,12},{09,04,43}}).
 The Date tuple ({2013,9,6}) says today is: 2013/9/6,
 The time tuple ({9,4,43}) indicates: 9:4:43.
ok
6> functions:valid_time({{2013,09,06},{09,04}}).
 Stop feeding me wrong data!
ok
  • この関数は、タプルが{{A,B,C},{D,E,F}}の形をしている限り、値として文字列でもアトムでもなんでも受け付けてしまう

3.2 ガードだ、ガード!

  • ガードは、パターンマッチの表現力を高めるために 関数のヘッドに書ける追加の節
old_enough(X) when X >= 16 ->
    true;
old_enough(_) ->
    false.
  • ガード式の基本的なルールは、成功時に true を返さなければいけない
  • もし false を返すか、例外を投げるなら、ガードは失敗

複数条件の場合

right_age(X) when X >= 16, X =< 104 ->
    true;
right_age(_) ->
    false.

カンマ(,)は andalso 演算子と同じように振 る舞い、セミコロン(;)は orelse のように振る舞う

wrong_age(X) when X < 16; X > 104 ->
    true;
wrong_age(_) ->
    false.

3.3 If ってなんだ?!

  • if 節はガードのように振る舞い、ガードと同じような構文
  • 関数節の先頭の外側で使う
  • if節はガードパターンと呼ばれている
  • 他の言語で見てきた if とは異なる
-module(what_the_if).
-export([heh_fine/0]).

heh_fine() ->
    if 1 =:= 1 ->
        works
    end,
    if 1 =:= 2; 1 =:= 1 ->
        works
    end,
    if1 =:= 2, 1 =:= 1 ->
        fails
    end.
1> c(what_the_if).
./what_the_if.erl:12: Warning: no clause will ever match
./what_the_if.erl:12: Warning: the guard for this clause evaluates to 'false'
{ok,what_the_if}
2> what_the_if:heh_fine().
** exception error: no true branch found when evaluating an if expression in function what_the_if:heh_fine/0
oh_god(N) ->
    if N =:= 2 -> might_succeed;
        true -> always_does %% This is Erlang's if's 'else!'
    end.
3> c(what_the_if).
./what_the_if.erl:12: Warning: no clause will ever match
./what_the_if.erl:12: Warning: the guard for this clause evaluates to 'false' {ok,what_the_if}
4> what_the_if:oh_god(2).
might_succeed
5> what_the_if:oh_god(3).
always_does

わかりやすく置き換える例
これを

if X > Y -> a()
 ; true -> b()
end

if X > Y -> a()
 ; X < Y -> b()
 ; true -> c()
end

こう置き換える

if X > Y -> a()
 ; X =< Y -> b()
end

if X > Y -> a()
 ; X < Y -> b()
 ; X == Y -> c()
end

3.4 もしも...の場合(In Case ... of)

  • if式がガードのようなものだとしたら、case ... of式は関数のヘッド全体のようなもの
insert(X,[]) ->
    [X];
insert(X,Set) ->
    case lists:member(X,Set) of
        true -> Set;
        false -> [X|Set]
    end.
beach(Temperature) ->
    case Temperature of
        {celsius, N} when N >= 20, N =< 45 ->
            'favorable';
        {kelvin, N} when N >= 293, N =< 318 ->
            'scientifically favorable';
        {fahrenheit, N} when N >= 68, N =< 113 ->
            'favorable in the US';
        _ ->
            'avoid beach'
    end.
beachf({celsius, N}) when N >= 20, N =< 45 ->
    'favorable';
...
beachf(_) ->

3.5 どれを使えばいいの?

  • if、case... of、関数という3つのうち、どれを使う かは、わりと答えるのが難しい質問
  • 明らかな違いの 1 つは、1 つ以上の引数 が評価される時
    • function(A,B) -> ...はAとBに対してガードと値のパターンマッチを持てる
    • case 式では
case {A,B} of
    〔パターン〕〔ガード〕-> ...
end.