関数型プログラミング言語Haskell Part24
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2013/10/25(金) 21:54:29.92前スレ: 関数型プログラミング言語Haskell Part23
http://toro.2ch.net/test/read.cgi/tech/1376111807/
haskell.org
http://www.haskell.org/
日本語サイト
http://www.sampou.org/cgi-bin/haskell.cgi
http://www.shido.info/hs/
過去ログ (10〜)
Part21 ttp://toro.2ch.net/test/read.cgi/tech/1358702176/
Part20 ttp://toro.2ch.net/test/read.cgi/tech/1350428908/
Part19 ttp://toro.2ch.net/test/read.cgi/tech/1340760070/
Part18 ttp://toro.2ch.net/test/read.cgi/tech/1331902463/
Part17 ttp://toro.2ch.net/test/read.cgi/tech/1325510368/
Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
0655デフォルトの名無しさん
2014/01/26(日) 19:16:04.860657デフォルトの名無しさん
2014/01/26(日) 19:20:19.03>なぜなら、たとえば関数 viewRecords の定義は recordsSource $$ recordsSink だから。
そこにrecordsSourceを直接書く代わりにCへの引数として受けとるようにする
という話を>>644からずっとしてるつもり
0658デフォルトの名無しさん
2014/01/26(日) 19:20:48.91mainを想定してる
0659636
2014/01/26(日) 19:28:50.76飲み込みが悪くてすまんが、Cへの引数として受けとるというのが今ひとつ分からない。
もしかして、viewRecords 関数ではなく
f :: (MonadIO m) => Source m A -> m ()
f src = src $$ recordsSink
という関数を C に作れってこと?
で、viewRecords 関数の定義は f recordsSource にしろと?
もしそうなら、viewRecords 関数はどこに書く?
勘違いしてたらごめん
0660デフォルトの名無しさん
2014/01/26(日) 19:41:14.64たとえば、メインループを行う関数がCにあるなら、それを
loop :: (MonadIO m) -> Source m A -> Sink A m () -> m ()
loop source sink = input >>= \case ...
みたいに定義して、main内で、
runSqlite $ loop viewRecords recordsSink
みたいに呼ぶ
メインループがmain側にある場合も基本は同じで、mainが
viewRecordsを渡してやる
0661636
2014/01/26(日) 21:56:54.92あぁ、やっと言いたいことが分かったような気がする。
C の loop 関数では、具体的な viewRecords 関数などを内部で呼ぶ代わりに、
「データを流す役割のソース」や「データを変更する役割のシンク」や「データを表示する役割のシンク」
などといったソース群とシンク群を引数で受け取るようにして、それを使う。
で、main 関数内などの MVC を統括する部分で、実際に C の loop 関数に、
具体的なソースやシンクを渡すのか。
なるほど、とても参考になった。
0662636
2014/01/27(月) 19:04:10.08こっちも意味がわかった。
SQLへのアクセスに関わる部分(runSqlConn や runResourceT なども含めて)は
すべて M の中に閉じ込めることができてスッキリしたよ。
二人共ありがと
0663デフォルトの名無しさん
2014/01/27(月) 19:31:00.47こういうIDEがクラウドじゃなくて普通にインストールアプリとして欲しいのだが
0664デフォルトの名無しさん
2014/01/27(月) 23:06:17.38エディタの構文チェッカープラグインよりこっちの方が速いって一体w
このIDEもサーバ側も全部Haskell製(前者はFayでJSにしてあるけど)なんだなー、面白い
関係ないけど、Vim使いならSyntasticとghcmod-vim,neco-ghcあたりを入れればかなりIDEっぽく使えるのでお勧め
0665デフォルトの名無しさん
2014/01/30(木) 00:57:48.910666デフォルトの名無しさん
2014/01/30(木) 01:24:35.69誰に聞いたのそれ
0667デフォルトの名無しさん
2014/01/30(木) 01:31:03.56本当だよ
君も今すぐ使った方がいい
0668デフォルトの名無しさん
2014/01/30(木) 08:28:54.390669デフォルトの名無しさん
2014/01/30(木) 22:21:37.65本当だよ。
みんなもう使ってるよ。
早く使わないと取り残されるよ。
0670デフォルトの名無しさん
2014/01/30(木) 23:34:25.95というかモナドは時代遅れだよ
0671デフォルトの名無しさん
2014/01/31(金) 06:55:03.480672デフォルトの名無しさん
2014/01/31(金) 07:28:57.240673デフォルトの名無しさん
2014/01/31(金) 08:28:25.160674デフォルトの名無しさん
2014/01/31(金) 09:11:29.00もっと煽らないと……。
0675デフォルトの名無しさん
2014/01/31(金) 09:27:02.890676デフォルトの名無しさん
2014/01/31(金) 09:38:49.580677デフォルトの名無しさん
2014/01/31(金) 10:01:43.740678デフォルトの名無しさん
2014/01/31(金) 11:08:55.55なんで最初にそう聞かないの? いくらでも教えてあげたのに
おっとそろそろ出勤だ
0679デフォルトの名無しさん
2014/01/31(金) 14:22:14.08これは
uncurry (+) <<< (*100) &&& (*10) $ 2
こうすればいいですか><
app <<< (+) . (*100) &&& (*10) $ 2
0680デフォルトの名無しさん
2014/01/31(金) 19:11:40.60haskell-jaより引用:
(ikegami氏)
Arrow でつくると、疎結合の疎の具合がさらにゆるゆるになるので、多少の仕様変更にもすぐに対応できるかわりに
さらにスピードが低下する
仕様変更に対する強さ <-> スピード という両軸で見ると
Arrow <<< State/Reader/Writer monad << ST monad
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad-ST.html
ST は黒魔術なので、はっきりいっておすすめできない (が、スピードのために必要になるかもしれないので老婆心で)
0681デフォルトの名無しさん
2014/01/31(金) 19:14:56.120682デフォルトの名無しさん
2014/01/31(金) 19:21:47.200683デフォルトの名無しさん
2014/01/31(金) 19:52:15.51例えばIOモナド版と純粋関数版の二つを作らなければならないはずのところを
arrowで抽象化しておけば一つだけ作ればすむ
だからIOで使うつもりだった関数を急に純粋に変えたくなった
みたいな状況で仕様変更に強くなるか、と聞かれたらyesなのでは
もうarrowのことあまり覚えてないので間違ってたらゴメンネ
0684デフォルトの名無しさん
2014/01/31(金) 20:15:10.550685デフォルトの名無しさん
2014/01/31(金) 20:44:32.50純粋にしたいところだけidentityモナド使えばいい気がしてきた
やっぱarrowいらんわ。arrowは糞。
0686デフォルトの名無しさん
2014/01/31(金) 22:15:36.300687デフォルトの名無しさん
2014/01/31(金) 22:19:11.970688デフォルトの名無しさん
2014/01/31(金) 23:29:19.00愚弄?kwsk
0689デフォルトの名無しさん
2014/01/31(金) 23:55:35.640690デフォルトの名無しさん
2014/02/01(土) 23:27:57.78テストコードの書き方が分からん。
(参考資料 : https://github.com/kazu-yamamoto/unit-test-example/blob/master/markdown/ja/tutorial.md)
Exceptoin の bracket 関数を使って、
メイン処理の前後でリソースの確保と開放を行う関数 useResource(仮名)がある。
メイン処理サブ関数 f1、f2、..., fn があって、
メイン処理関数 f :: Resource -> IO a の中でそれらが呼ばれ、処理される。
もちろん、f1、f2 らはそれぞれ useResource 関数で確保したリソースを使う。
本来なら f に useResource を適用して一連の処理を行うのだが、
今は個々の f1、f2、..., fn をテストしたい。
こういう状況の場合、HSpec 用の t :: Spec 関数はどう書くのが一般的なのかな。
describe "〜〜〜"
it "〜〜〜" $ do
[ここ]
[ここ] に useResource を書いて f1 や f2 などをそれぞれぶち込んで
結果を正常値と比較したり、例外の発生をテスしたりすると、
個々のテスト毎にリソースの確保と開放が発生するよね。
cabal で自動テスト実行するなら、これは仕方ないのかな?
もしリソースがデータベースとかで、テストで QuickCheck を使ってたら、
けっこう悲惨なことにならない?
0691デフォルトの名無しさん
2014/02/02(日) 13:25:55.74時系列で変化するものは、一般的に考慮が必要。
単体テストなら
・関数的な結果を返すモックにする
・DBの中身が変わらないことを前提に、トランザクションで囲んで、rollbackさせる
(comitされる処理は対応出来ない、serialやoid消費される前提)
現在時間などの変数に注意。
結合やシナリオということであれば、
・DB初期化、シード投入、実行
・組み込みDBなら、スナップショット切り替え、実行
quickcheckに組み合わせるのは、基本モックなのではという気がする。
0692デフォルトの名無しさん
2014/02/02(日) 13:53:47.77あぁ、なるほど、こういう場合にモックを使うのか
ありがと、やってみるよ
0693デフォルトの名無しさん
2014/02/02(日) 14:56:44.18HSpec に test-framework をかぶせて使ったのだけど、
テスト結果を Jenkins で使える XML 形式で出力するにはどうすればいい?
0694693
2014/02/02(日) 15:44:56.64現状無理だったわ
スレ汚してすまんかった
0695693
2014/02/02(日) 16:10:21.20>>690 の状況をシンプルにすると、
モジュール A の中でデータベースを使っていて、
データを出したり書き込んだりする関数が公開されている。
このモジュール A が公開している関数をテストしたい。
もちろん、モジュール A は変更を一切加えること無く。
データベースの接続などはコストが高いのでテスト時はモックを使う、となると、
そもそもモジュール A はデータベースへ直接アクセスしていてはダメだということか?
例えば、データベースへのアクセスを抽象化した型クラスを作り、
そのインスタンス型の値を外部からもらって、それを使ってアクセスするようにしておかないと、
データベースのモック化はできない、という認識でいいのかな?
0696デフォルトの名無しさん
2014/02/02(日) 22:11:50.43コンテキストの部分をクラス変数みたいなのでパラメータ化できないでしょうか。
たとえば
class C c where
f :: (??? t) => Int -> t
のようなクラス宣言があったとして、この ??? の部分を
型クラス C のインスタンス型毎に変えたいです。
{-# LANGUAGE InstanceSigs #-}
instance C X where
f :: (ClassA a) => Int -> a
f v = ...
instance C Y where
f :: (ClassB b) => Int -> b
f v = ...
このようなことは可能でしょうか。
0697696
2014/02/02(日) 22:18:14.41すいません、関数 f を使う時に
コンテキスト制約に使ったクラス ClassA から型 X のものであること、
コンテキスト制約に使ったクラス ClassB から型 Y のものであることが推論できるように
ということです。
そのような推論ができなければ、クラス C の定義において
関数 f の引数か戻り値に c を入れておくことで対処しますが、
とにかく >>696 のような使い方ができるクラス変数なるものはあるか、という質問です。
0698デフォルトの名無しさん
2014/02/02(日) 22:18:19.82{-# LANGUAGE ConstraintKinds, TypeFamilies #-}
class C c where
type Constr c :: * -> GHC.Exts.Constraint
f :: (Constr c t) => Int -> t
0699698
2014/02/02(日) 22:19:52.53{-# LANGUAGE ConstraintKinds, TypeFamilies#-}
import GHC.Exts
class C c where
type Constr c :: * -> GHC.Exts.Constraint
f :: (Constr c t) => Int -> t
>>697
>コンテキスト制約に使ったクラス ClassB から型 Y のものであることが推論できるように
具体的にどういうコードでどういう推論が起こって欲しい?
0700696
2014/02/02(日) 23:19:48.44ありがとうございます。
そのやり方で、インスタンス毎にコンテキスト部分をかえることができました。
ついでに、ConstraintKinds や TypeFamilies を調べている特に、
次の方法でも似たようなことができる事が分かりました。
{-# LANGUAGE MultiParamTypeClasses, ConstraintKinds, TypeFamilies #-}
class C c p where
f :: (p t) = Int -> t
instance C A X where
f :: (X t) => Int -> t
f v = ...
instance C B Y where
f :: (Y t) => Int -> t
f v = ...
> 具体的にどういうコードでどういう推論が起こって欲しい?
今回挙げた例で言えば、
g :: (X t) => t
g = f 7
という使い方をすれば B の f ではなく、A の f だとみなされると嬉しいです。
0701デフォルトの名無しさん
2014/02/03(月) 06:07:38.67>次の方法でも似たようなことができる事が分かりました。
そのコードならTypeFamilies拡張要らないな
>>699の場合ではConstrという関連型を宣言するのに必要だった
>g :: (X t) => t
>g = f 7
>
>という使い方をすれば B の f ではなく、A の f だとみなされると嬉しいです。
これは無理だと思う。fの型は
f :: (C c p, p t) => Int -> t
だけど、gの型シグネチャからは(X t)から(p t)が言えることが要請されるだけで、
p=Xが確定する訳じゃないので、情報が足りない
0702696
2014/02/03(月) 07:09:51.19あの後いろいろ試してみたのですが、自分で見つけた方法の方は、
今回の目的に関して言えば、どうも使い勝手が悪いです。
> これは無理だと思う。fの型は ・・・
このことと関連しますが、自分のやり方だとクラス内の全ての関数で、
class C c p where の c と p をシグネチャのどこかに入れないと推論できない。
class C c p where 程度ならまだなんとかなりますが、
class C c x y z ... where と少し増えただけでとても不便になりました。
その点 >>699 の方法は柔軟性があるので使いやすかったです。
> gの型シグネチャからは(X t)から(p t)が言えることが要請されるだけで、
> p=Xが確定する訳じゃないので、情報が足りない
やはりそのようですね。
こちらの方は諦めます。
0703デフォルトの名無しさん
2014/02/08(土) 10:15:20.05f :: a という関数シグネチャがあって、この関数 f の定義として、
a が Int 型だった場合のみ特別な事をして、そうでない型の場合は一般的な事をする。
f :: Int
f = 特別な何か
f :: a
f = 一般的な何か
みたいな。
0704デフォルトの名無しさん
2014/02/08(土) 10:28:07.17「特別な何か」と「一般的な何か」が意味的に同じ(違うのは効率だけ)なら、
書き換え規則で後者を前者に書き換えるのがおすすめ
意味的に違うならOverlappingInstancesしかないけど、
いろいろ厄介なので、使わないで済むなら使わないのを勧める
0705デフォルトの名無しさん
2014/02/08(土) 10:32:45.93ありがとうございます。
調べてみます。
0706デフォルトの名無しさん
2014/02/08(土) 11:20:08.66予め ghc でコンパイルして *.hi ファイルを作っておくことで、
対となる *.hs ファイルをロードすれば ghci 上でも書き換え規則が適用されるんですが、
*.hi ファイルの無い *.hs ファイルのロードのみでも適用する方法って無いでしょうか。
ちょっとだけ不便です。
「そう言えば忘れてた」と思って *.hs の内容をちょっと変更して、
ghci 上で再ロードした時に、書き換え規則が適用されず「あれ?」となり、
*.hi ファイルを出していなかったことを思い出すまで時間がかかったり・・・
ghci 上でちょっとした修正と実行テストを繰り返す場合など、なかなか面倒だったりしますよね。
0707デフォルトの名無しさん
2014/02/08(土) 15:23:45.64書き換え規則は最適化の一種なのでghciでは使えないっぽいね
0708デフォルトの名無しさん
2014/02/09(日) 10:07:53.53やはりそうですか。
これは我慢するしか無いですね。
将来のバージョンでは書き換えなど
最適化してロードされるオプションも付けて欲しいです。
0709デフォルトの名無しさん
2014/02/09(日) 13:16:16.81要望はglasgow-haskell-usersへ
0710デフォルトの名無しさん
2014/02/09(日) 13:48:25.21英語が書けないから、要望を出すのは諦めました。
0711デフォルトの名無しさん
2014/02/09(日) 14:16:48.510712デフォルトの名無しさん
2014/02/09(日) 15:01:31.44今のところ全く問題ないです。
読むことはできるので。
0713デフォルトの名無しさん
2014/02/09(日) 15:17:42.320714デフォルトの名無しさん
2014/02/09(日) 15:28:59.34例外が発生しない状態だとテストに失敗しとたとみなす、という意味だけど。
0715デフォルトの名無しさん
2014/02/09(日) 15:42:38.26例外が投げられたら捕捉してTrueを返し、そうでなければFalseを返すようなアクションを書いて、
それを(@?)かなにかを使ってテストにすればいいと思う
0716デフォルトの名無しさん
2014/02/09(日) 15:57:11.06やっぱそういう事になるのか
例外をテストする関数か何かライブラリにあっても良さそうなもんだが・・・
ありがと
0717デフォルトの名無しさん
2014/02/09(日) 21:06:40.67testGroup "Test Group1"
[ testCase "Test1" test_something1
, testCase "Test2" test_something2
]
というテストグループがあったとして、
test_something1 のテストに成功した場合のみ
test_something2 のテストを行う、ということはできる?
試しに test_something2 のテストを testGroup で囲ってみたが、
何も変わらなかった(普通にテストされる)。
0718デフォルトの名無しさん
2014/02/09(日) 21:51:36.15やりたいことは、コンソールの一部領域だけスクロールするように見せたり、
プログレスバーを表示させたりするような CUI アプリを作ることです。
0719デフォルトの名無しさん
2014/02/09(日) 22:13:31.77個人的に使っているのは、この二つ。
CUIフレームワークなら: http://hackage.haskell.org/package/ncurses
自分で細かく制御したいなら: http://hackage.haskell.org/package/ansi-terminal
0720デフォルトの名無しさん
2014/02/09(日) 23:38:28.96じゃあかんの?
0721717
2014/02/10(月) 20:05:23.49俺へのレスだったか、すまん気づかんかったわ
あかんも何も、tasty というテストフレームワークの存在を初めて知ったから、まだ分からん
tasty-ant-xml 使って jenkins とも連携できそうだから、ちょっと試してみるよ
0722717
2014/02/10(月) 20:35:59.86使ってみたが分からんかった
tasty-rerun でどうやれば >>717 を実現できる?
--rerun-filter オプションで指定できる 4 つのオプションを組み合わせるってこと?
0723デフォルトの名無しさん
2014/02/10(月) 22:58:24.76調べてみたところ、出力なら ansi-terminal で十分であることが分かりました。
ただ入力側も扱いたいので ncurses を使おうとしましたが、
パッケージのインストール時に外部ライブラリとして ncursesw/ncurses.h が必要です。
私の使っている ArchLinux ではどうもこの ncursesw を使うのに一手間かかるようで、
その一手間がどういったものか情報が得られませんでした(ncurses.h 自体はある)。
正確に言えば、私が理解できる情報が得られなかったわけですが。
もう少し調べてたところ、vty というパッケージがあることが分かりました。
"vty is terminal GUI library in the niche of ncurses." とのことです。
これで行けそうな気がします。
アドバイスありがとうございました。
0724デフォルトの名無しさん
2014/02/12(水) 02:04:22.00でもHayooでは引っかかる。
みんなHayoo使ってるんですかね?
0725デフォルトの名無しさん
2014/02/12(水) 07:16:28.780726デフォルトの名無しさん
2014/02/12(水) 08:33:32.47Hayooメインで使ってる。
でも、サービスがよく止まってるから、結果的にHoogleも併用してる。
0727デフォルトの名無しさん
2014/02/12(水) 15:23:24.760728デフォルトの名無しさん
2014/02/12(水) 21:51:44.15documentation: True
にしてから
cabal install world --reinstall
すると、ドキュメントもローカルに落とせるんですね、、知らなかったです。
これをhoogleコマンドから引けたらもっといいんですけど、どうすればいいのかよくわからない…
0729デフォルトの名無しさん
2014/02/12(水) 22:37:44.600730デフォルトの名無しさん
2014/02/13(木) 12:02:34.01字幕をONにして見てね。
http://www.youtube.com/watch?v=ABsutPSLuqQ
0731デフォルトの名無しさん
2014/02/13(木) 23:18:36.850732デフォルトの名無しさん
2014/02/13(木) 23:43:40.46本家はjavaだっけ?処理速度的にどうなのか気になる
0733デフォルトの名無しさん
2014/02/14(金) 00:52:31.90ただ細かな部分での最適化はそれほどでもないみたい?
0734デフォルトの名無しさん
2014/02/14(金) 00:58:45.260735デフォルトの名無しさん
2014/02/14(金) 01:00:44.40コード見たい
0736デフォルトの名無しさん
2014/02/14(金) 01:11:56.29完成したら公開する予定って G+ で言ってる
0737デフォルトの名無しさん
2014/02/14(金) 08:25:47.90書きなぐった感じで作ってもそれぐらいだったよ。
偉い人が書くと余裕で半分以下になると思う。
処理速度は他言語で似たようなもの作ったことないから
比較できない・・・。
ただ、直感的にFortranと比べると若干遅い気がする。
表面に出るブロックだけピックアップして描画してるんだけど、
ピックアップするときに50万ブロックの走査したら数秒かかったw
>>733
今回のコードは8割以上IOモナドに浸食されてるんで・・・。
>>735-736
動画の最後でも言ってるんだけど、やはり大方の人に
最後まで見てもらえてなさそうだなw
0738デフォルトの名無しさん
2014/02/14(金) 12:28:32.57動画最後まで見たけど、早送り気味で見たから。
0739デフォルトの名無しさん
2014/02/14(金) 13:05:58.50そっか。
最後までみてくれてありがとう。
0740デフォルトの名無しさん
2014/02/14(金) 13:09:34.88それでも別に融合変換は出来るのでは?
0741デフォルトの名無しさん
2014/02/14(金) 13:56:47.97>>733の副作用に条件反射して答えちゃいました
そもそも融合について名前程度しかしらなかったので
「関数プログラミングの楽しみ」やRWHの該当箇所を
流し読みしてみた。
でも、アドレス変換して値を参照してるところを直値を
直接参照して計算するようにプログラムを変換してくれ
るのかな・・・程度にしかわからなかった orz
もしその理解で正しいなら、この技法を取り入れたら
かなり早くなりそう。
難しいことは避けてきたけど、そろそろ真面目にHaskell
を勉強します・・・ m(_ _)m
0742デフォルトの名無しさん
2014/02/14(金) 23:45:37.62直接参照云々はUNPACKのことかな。これも確かに高速化に繋がるけど、融合変換とか副作用とかとはあんまり関係ない
0743デフォルトの名無しさん
2014/02/15(土) 00:33:12.68説明の仕方が悪かったです。
中間のデータ構造を省いて必要な値を直接参照するように変換するような
もののような気がします。
例えば、以下のようなデータ構造があって、ある関数が特定の箇所を
走査する場合に以下のように変換するようなイメージだと理解しました。
data Aaa = Aaa { bb :: Double, cc :: Bool}
func :: [Aaa] -> Double
func aaa = foldl (\ s (Aaa {bb=d}) -> s + d ) 0 aaa
この関数を以下のように変換してくれる?
func aaa = foldl (+) 0 aaa'
where
aaa' = map (\ Aaa {bb=d}) -> d) aaa
UNPACKとの違いはよく分かりません・・・。
0744デフォルトの名無しさん
2014/02/15(土) 00:43:05.59>>743では変換後もリストを使ってますが、そのリストが直値の配列
になってるような感じだと思いました。
上手く説明できずスミマセン。
コンパイラの最適化で自動的にやってくれることのような気もします・・・。
ただ、副作用の有無は最適化時に重要になってくるような気もします・・・。
0745デフォルトの名無しさん
2014/02/15(土) 01:02:57.590746デフォルトの名無しさん
2014/02/15(土) 08:14:19.73逆じゃね?
0747デフォルトの名無しさん
2014/02/15(土) 12:55:05.47結局のところ、どうなんでしょう・・・。
ただ、副作用があると難しそうですよね。
>>746
言わんとしてることは分かります。
たぶん、会話が噛みあってないだけだと思います。
0748デフォルトの名無しさん
2014/02/15(土) 13:12:05.42よっぽど暇な学科なんだろうなって思う
0749デフォルトの名無しさん
2014/02/15(土) 13:26:34.990750デフォルトの名無しさん
2014/02/15(土) 13:41:28.47「僕、今ハスケルで君の美を表現してるんだ」
これで芸大女ともやれるな
よぉぅしっ
0751デフォルトの名無しさん
2014/02/15(土) 13:49:04.850752デフォルトの名無しさん
2014/02/15(土) 13:58:18.440753デフォルトの名無しさん
2014/02/15(土) 14:00:19.630754デフォルトの名無しさん
2014/02/15(土) 15:01:07.79いまどきスマホのCASでもできちゃうから
■ このスレッドは過去ログ倉庫に格納されています