Skip to content

Instantly share code, notes, and snippets.

@pirapira
Forked from kazu-yamamoto/gist:461006
Created July 7, 2010 05:09
Show Gist options
  • Save pirapira/466330 to your computer and use it in GitHub Desktop.
Save pirapira/466330 to your computer and use it in GitHub Desktop.

function-data/relation mapper

スキーマ

table mail {
    id int primary key,
    from_addr varchar[50],
    date datetime,
    mailbox varchar[50]
}
  • Ord id, Ord datetime
  • Eq from, Eq mailbox

設問1 (filter)

差出人が alice@example.com のメールを全部取得

入力: '(filter (lambda (x) (equal? (from_addr x) "alice@example.com")) (mail)) $(filter (\x -> fromAddr x == "alice@example.com"))

出力: "select * from mail where from_addr='alice@example.com'"

議論:S式中の自由変数はなくすべきでは? '(lambda (mail) (filter (lambda (x) (equal? (from_addr x) "alice@example.com"))) mail)

  • そうでもないと思う.SQLでもmailは自由変数.lambdaでmailを束縛してしまうと,α変換した '(lambda (tale) (filter (lambda (x) (equal? (from_addr x) "alice@example.com"))) tale) と同じ意味になるべきで,出力にmailが出現するのがおかしいことになってしまう.

設問2 (sort)

日付順にメールを全部取得。

入力: (sort (lambda (x y) (< (date x) (date y))) (mail)) $(sortBy (\x y -> data x < date y))

出力: "select * from mail order by date asc"

設問3 (map, sort)

差出人メールアドレスのドメインのみを取得。

入力: (map domain (map from_addr (mail))) $(map (domain . fromAddr))

出力: "select domain(from_addr) from mail"

設問4 (fold)

メールボックス毎にメール数を取得。

入力: (fold (lambda (next summary) (let ((current (assoc (mailbox next) summary))) (if current (acons (mailbox next) (+ 1 (cdr current)) (assoc-delete (mailbox next) summary)) (acons (mailbox next) 1 summary)))) '() (mail))

出力: "select count(*) from mail group by mailbox"

設問5 (filter, map, sort)

最新 1 週間以内のメールを日付が新しいものから順に最大20件取得。

入力: (take (sort (lambda (x y) (> (date x) (date y))) (mail)) 20) $(take 20 (sortBy (\x y -> date x > date y)))

出力: "select * from mail order by date desc limit 20"

設問6 (filter, map, sort, fold)

差出人毎に、メールアドレスとそのメール数をメール数が多い順に最大20件取得。

入力:?

出力: "select from_addr, count(*) as A1 from mail group by from_addr order by A1 desc limit 20"

設問7 (sort, join)

メールボックス box1 に存在しメールボックス box2 に存在しないメールを最新のものから順に全部取得。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment