第3回 スタートHaskell 感想
今回はニフティで開催。大森駅には初めて降りた。住宅街とオフィス街が混ざったような雰囲気だった。
発表
極意
バグの入り込みにくい小さな関数をつなげて、大きな関数を作る。
速度
length は遅い。あと rverse も。配列をすべて走査しないといけないから。途中で打ち切れない。
再帰
「一つ前ができていたら、次はどうする?」(c) 和田先生.
畳み込み
foldr は末尾再帰でない再帰。遅延評価と相性がいい。リストを生成する関数と相性がいい。
foldl は末尾再帰。数値を生成する関数と相性がいい。
and や or を 畳み込みを使って実装する場合は、リストを生成する関数ではないが foldr の方がいい。
and' :: [Bool] -> Bool and' = foldr (&&) True
and の場合 (&&) の定義が
True && x = x False && _ = False
となっているため、途中で False が見つかればそこで処理を打ち切れる。末尾再帰を使うと以下のようなコードの場合、返ってこない。
and $ map (<= 10) [1..]
演習
型(Kata)の練習。3時間は長いな〜と思ったけど、あっという間だった。
虎さんが用意してくださった演習はとてもやりやすかった。いつもありがとうございます。
Sinatra, OmniAuth メモ
遅ればせながら OmniAuth を使ってみた。とても便利だったのでメモしておく。
サンプル
手順
Step 0
https://dev.twitter.com/ でアプリを登録。登録時に発行される Consumer key, Consumer secret は後で使う。
Step 1
Gemfile を作成して。bundle install を実行。
% bundle install
Step 2
config.ru を作成。
Step 3
app.rb を作成。
Step 4
環境変数の設定。 Step 0 で得た Consumer key, Consumer secret を設定。
% export TWITTER_CONSUMERKEY=Consumer key % export TWITTER_CONSUMERSECRET=Consumer secret
Step 5
起動。ブラウザで動作確認。
% bundle exec rackup config.ru
第2回 スタートHaskell 感想
今回は参加者が 100 名以上いた前回までとは違い、50名強の参加者だった。人が少ないなと思ったが、勉強会としては多い方だろうな。
第 1 部
予習してきた部分の発表。発表だけかと思いきや熱い議論が始まる展開に。初心者向けの勉強会と銘打たれているが、Haskellに詳しい方も参加されているので、いろいろとためになる話が聞けてよかった。
第 2 部
演習。本当に初心者向け?皆さん解くのが速い。
elem は中置記法
Haskeller は
elem 'c' "abcdefg"
よりも
'c' `elem` "abcdefg"
と書く人が多いらしい。英語のように読むことができるので。elem に限った話ではないけど。
-Wall -O
ghc(i) の実行時には -Wall と -O のオプションを付けるべし。-Wall は警告をすべて表示させる。-O は最適化を行う。gcc のオプションと同じ。
ただ問題が。-Wall を付けることで実行時に警告が出力される場合がある。コンパイル時には警告は出ない。これはちょっと使いづらい。
% ghci -O -Wall section7_13.hs GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. [1 of 1] Compiling Main ( section7_13.hs, interpreted ) Ok, modules loaded: Main. *Main> nmerge [[9],[2,5,7],[1,4],[],[3,6],[8]] <interactive>:1:37: Warning: Defaulting the following constraint(s) to type `Integer' (Num a0) arising from the literal `8' at <interactive>:1:37 (Ord a0) arising from a use of `nmerge' at <interactive>:1:1-6 In the expression: 8 In the expression: [8] In the first argument of `nmerge', namely `[[9], [2, 5, 7], [1, 4], [], ....]' <interactive>:1:37: Warning: Defaulting the following constraint(s) to type `Integer' (Num a0) arising from the literal `8' at <interactive>:1:37 (Ord a0) arising from a use of `nmerge' at <interactive>:1:1-6 (Show a0) arising from a use of `print' at <interactive>:1:1-39 In the expression: 8 In the expression: [8] In the first argument of `nmerge', namely `[[9], [2, 5, 7], [1, 4], [], ....]' [1,2,3,4,5,6,7,8,9]
書き方が悪いのかと思ったが http://haskell.org/ghc/docs/7.0.3/html/users_guide/options-sanity.html を見ると、-fwarn-type-defaults が原因のようだ。なので -fwarn-type-defaults をなくしてみる。オプションは -fno-warn-... とすることで off にすることができる。
% ghci -O -Wall -fno-warn-type-defaults section7_13.hs GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. [1 of 1] Compiling Main ( section7_13.hs, interpreted ) Ok, modules loaded: Main. *Main> nmerge [[9],[2,5,7],[1,4],[],[3,6],[8]] [1,2,3,4,5,6,7,8,9]
消えた。毎回打つのは面倒なので ~/.ghci にオプションを追加。
~/.ghci
:set -O :set -Wall :set -fno-warn-type-defaults
数
Haskell のコードを書いていてよくハマるのが数値の型変換のところ。fromRational, toRational って何ですか。
*Main> :t fromRational fromRational :: Fractional a => Rational -> a *Main> :t toRational toRational :: Real a => a -> Rational
英語が不得意な自分のために書いておくと
Rational -- 有理数 Real -- 実数 Fractional -- 分数
有理数と分数の違いが...。
クラスの階層関係は http://www.sampou.org/haskell/report-revised-j/basic.html#standard-classes で。数関連のクラスは複雑。
MySQL で既存の非 TEMPORARY テーブルと同名の TEMPORARY テーブルを作成する方法
テストで TEMPORARY テーブルを使いたかったときの話。
Good
CREATE TEMPORARY TABLE tbl_name SELECT * FROM tbl_name LIMIT 0 -- テーブルだけを作成したいときに
ただし
CREATE TABLE ... SELECT は自動的にインデックスを作成しません。
http://dev.mysql.com/doc/refman/5.1/ja/create-table.html
なので、インデックスが必要な場合には別途作成する必要がある。
Bad
LIKE だと名前が重複しているぞ、というエラーになった。
CREATE TEMPORARY TABLE tbl_name LIKE tbl_name
第1回 スタートHaskell 感想
会場に着いたのが 19 時 10 分頃。ちょうど勉強会が始まる頃だった。
発表
今回の勉強会の対象の 2, 3, 4 章のまとめの発表。基本的には本に書かれている内容なので新たな発見は少なかった。
コメントはネストできる。
複数行のコメントは {- -} で囲む。コメントの中にコメントを含められる。
{- {- ここはコメント -} ここもコメントになる -}
n + k パターンがなくなった理由
パターンマッチにはデータ構成子しか使えない。
演習
補足の演習問題の量が多いので、あらかじめ練習問題は済ませておいた方がいいと思った。問題の答え合わせがなかったので、これでいいのかどうなのかがわからない。今回の範囲の内容であればそれでもいいかもしれないが、先へ進んだ場合に答え合わせ+解説がないとつらいかもしれない。
宿題
今やってます。
Sequel で別名を付けたりテーブルを指定したりする
Sequel でカラムに別名を付けたり、どのテーブルのカラムなのかを指定する方法のメモ。
require 'sequel' DB = Sequel.sqlite Sequel::Model.plugin :schema class Tbl < Sequel::Model unless table_exists? set_schema do primary_key :id end create_table end end p Tbl.select(:id).filter(:id => 1).sql # => "SELECT `id` FROM `tbls` WHERE (`id` = 1)" p Tbl.select(:id___pk).filter(:tbls__id => 1).sql # => "SELECT `id` AS 'pk' FROM `tbls` WHERE (`tbls`.`id` = 1)" p Tbl.select(:tables__id___pk).sql # => "SELECT `tables`.`id` AS 'pk' FROM `tbls`"
カラム名 + "___" + 別名 で別名を付ける。
テーブル名 + "__" + カラム名 で テーブルを指定。
アンダーバーを使ったカラム名は避けたい。
ツイッターの認証で毎回アプリの許可画面が出る件について
今作っている Web アプリでツイッターの OAuth 認証をする際、毎回このアプリを許可するかどうかの確認画面が表示されていた。以前作ったアプリではそんなことはなかった。
調べたら、認証用の URL は oauth/authenticate と oauth/authorize の 2 種類があった。
今のアプリが使っているのは oauth/authorize だったので、oauth/authenticate に変えてみたところ、アプリの許可確認画面は表示されなくなった。ちなみに、許可確認画面の表示/非表示の違いがその 2 つの本質的な違いではない。
デスクトップアプリでは必ず oauth/authorize の方を使えとあるが、今作っているのは Web アプリなので oauth/authenticate を使うことにして解決。