関数型プログラミング言語Haskell Part9
・日本語の扱いについて
Haskell98によると、Charは一つのUnicode文字を表す(6.1.2)。
これに従って、比較的新しいHugsやGHC(6.4系を含む)ではCharは32ビット整数になっている。
ただし、どちらも入出力に際しての変換が完全でない。具体的には、
・ソースコード中の文字列リテラル
・System.IOライブラリでの入出力
が問題になる。
1. GHC6.4.2以前
ソースコード・入出力ともLatin-1を仮定する。Latin-1ではバイト値と
コードポイントが一致するので、入力時には外部エンコードの各バイトがそのままCharに
入り、出力時にはCharの下位8ビットのみが出力されるような実装になっている。
このため、あるエンコーディング(Latin-1とは限らない)の入力をgetLineで受け取り、
それをそのままputStrで表示すれば、入力時とおなじエンコードにおいて正しく表示される。
これを利用して、[Char]を、本来のコードポイントの列としてではなく、特定のエンコードの下での
バイト列として使うことができる。ただし文字列リテラルについては、GHCはLatin-1として
不正な文字を受け付けないので、EUC-JPのような例外を除くと、単純にリテラルを使うことはできない。
2. GHC6.6
ソースコードにはUTF-8、入出力にはLatin-1を仮定する。このため、EUC-JPでリテラルを直に
書くことはできない。
(続く)
(続き)
3.最近のHugs(非WindowsかつCのwchar_tがUnicodeの環境、というかLinux)
ソースコード・入出力ともロケールのエンコードを利用する。
4.最近のHugs(Windows)
ソースコード・入出力ともLatin-1を仮定する。ただし文字列リテラルにShift-JISを使ってもエラーにならない。
5.最近のHugs(それ以外)
未調査。
・結局どうするか。
規格どおりにCharにUnicodeを入れるか、Charを単なるバイトとして扱うかの二択。
i. CharをUnicodeとして扱う
(3)以外の場合入出力で変換が必要。(2)または(3)以外の場合文字列リテラルでは
明示的なエスケープ(たとえば"\22234")が必要。
ii. Charをバイトとして扱う
(3)ではファイルをバイナリモードで開くなどの対策が必要。(1)でEUC-JPを使う場合と(4)
を除き文字列リテラルでは明示的なエスケープ(たとえば"\143\153")が必要。
lengthやisAlphaのような関数、およびwin32パッケージの関数(win32API)が正しく動作しない。
テンプレはここまで。
前スレが終わってからしばらく建ってなかったので建てました。
行き届かないところがあったらごめんなさい。
_
, '´ λ ヽ
!,.イリノ)))〉
リ)^ヮ^ノ| このスレのマスコットキャラ
ノ⊂)水!つ
((( く/_l〉 リ はすけるたん
`` し'ノ
8 :
デフォルトの名無しさん:2008/05/17(土) 18:53:58
質問です
Word8からWord32に変換する方法についてなのですが、
Word8からtoInteger・fromInteger関数を経てWord32に変換する以外に、
クレバーな方法はありませんか?
>>8 n(n-1)個のcastを用意するのが
2n個のcastを用意するよりクレバーだと思いますか?
11 :
デフォルトの名無しさん:2008/05/17(土) 20:00:31
そろそろ、テンプレの GHC 6.6 の日本語の取り扱いについて書き改めて欲しい。
1. ソース中の文字列 hello = "こんにちは" :: String は UTF-8
2. これを ghci で表示することは可能:(ただし、環境変数 LANG を UTF-8 にしておくこと、また、ターミナルも UTF-8 で入出力できるようにしておくこと)
Main> print hello
こんにちは
Main>
3. 入出力 IO は Latin-1 だが、package utf8-string (
http://code.haskell.org/utf8-string/) を導入することにより、入出力を UTF-8 にすることができる
4. その他の文字列エンコード(ShiftJIS, JIS, EUC-JP など) は、package iconv (
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/iconv) で UTF-8 な文字列にする
とまあ、こういうことで、日本語表示できるわけだ。iconv package は MacOSX と *BSD では cabal を少しいじらなければいけないことに注意しろよ(iconv.cabal のコメントに書いてある)
よろしくたのむ、な。
12 :
sage:2008/05/17(土) 20:05:38
>>8 toEnum . fromEnum でよくね
>>11 >1. ソース中の文字列 hello = "こんにちは" :: String は UTF-8
これどういう意味?Stringになってしまえば文字コード関係なくね?
>2. これを ghci で表示することは可能
*Main> print hello
"\12371\12435\12395\12385\12399"
こうなった
>>8 fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral = fromInteger . toInteger
という関数がある
fromIntegralはGHCだといろいろ特殊化されてて効率もいいしな
新スレ乙です。
上げていただいている関連書籍で、
・Introduction to Functional Programming Using Haskell
・Haskell: The Craft of Functional Programming
は読み終えて、
・The Haskell School of Expression: Learning Functional Programming Through Multimedia
を問題解きつつ進めているところですけど、
・The Fun of Programming
次はこちらがいいんでしょうか。それともネット上の新しい記事とかを
見ていくほうがいいですか?
質問です。
100MB程度の音楽データを編集するツールを作ろうと思っているのですが、
音楽データを格納するための型のお勧めは何ですか?
音楽データって波形データ?
音楽ツールのことは良く知らないから一般的なことだけ言うと、
Haskellで配列っぽいデータを扱うときに一番空間効率がいいのは非ボックス化配列
(具体的にはUArrayかIOUArrayかSTUArray)で、Cの配列と同じくらいコンパクト
ただし、これは生の配列だから切ったり貼ったりするのには向かない
切り貼りしたいなら、「非ボックス化配列を葉とする木」みたいな構造が必要かも
ところで音楽編集ソフトって全部メモリ上で作業するんだろうか
>>17 ありがとうございます。文系なので理解できるか不安ですがw。
一通りの基本構文については馴染んできたと思うので、もう少し
アプリ全体の構成などについての解説文書みたいなものって
ありますでしょうか。
或いは、モナドもその一つだと思うのですが、関数型によるプログラミング
テクニックというんでしょうか、そういったものがもう少しまとまっている
本があると嬉しいんですが。
文系出身のやつって知ったかぶり多いよな。
細かいこと考えないのが吉なのか凶なのか。
絶対的な真理は無いという事を知ってるからじゃないかな。
理系は論理を重視するんだよ。
真理?なにそれ食えるの?
例えば
4 :: Int
は絶対的な真理じゃね?
論理は文系だろ
はい?俺理系なんで良く分かりません。
ささ、次行きましょう
>>24 その例のようなことが成り立つ数体系が便利だから、
たまたま人間が採用して「正しい」として使ってるだけとも言える
とはいえ、「数学は人間の存在にかかわらず成立するから
数学はこの世の真理の一つだ」と主張する哲学者もいたような
哲学者なんてはったり言うだけのでくの坊だろ 次行くぞ次
理系のやつって細かい事考えないんだな。
>>27 言葉が足りなかったな
Haskell98における式「4」は、Haskell98における型式「Int」で表される型を持つ
と言えばよかったか
もちろんHaskell98ってのは地球でBC1998年に定義された「あの」Haskell98のことで、
「型」とか「式」とかの術語はHaskell98の仕様に従って解釈するものとしてね
真理に「絶対的」なんて付けてるところを見ると
真理の意味が分かってないんだろ
真理の意味をお願いします
真理・・・いつもどんな時も変わることのない、正しい物事の筋道。真実の道理。
例:HaskellスレはHaskellを論ずる為に存在している
これでおk?
理系の雑談っていつもこんななの?
「真理」は既に絶対的なものだから「絶対的な真理」という表現は「絶対的」が重複しているってことだろ
>>35 理系に限らず2chの雑談はどこもこんな感じです。
今日はいつにもましてバカが多いな
春か?春だからなのか?
>>37 修飾語は強調する為にも使うけど、意味内容の重複は許されないという主張?
程度の存在しない物に強調もクソもないだろ
あ、強調って分かり辛かったか。念押しだと考えてみな。
程度の存在しない物に念押しもクソもないだろ
まさに自転車置場の議論
45 :
デフォルトの名無しさん:2008/05/19(月) 18:57:28
+++ってどういう意味なんですか?
+とか++とかもあってよくわからないのですが
>>30 × haskell4000年の歴史
○ AD
>>45 (+) は Integralクラスのインスタンス、つまり数の加法。
(++) は リストの結合。[1, 2, 3] ++ [4, 5, 6] は [1,2,3,4,5,6]。
(+++) は Arrowの合成かなにかに使う。Arrowは俺も良くわかんないし、まあ知らんでもプログラムは書けるから気にするな。
>>48 失敬!(+)はIntegralじゃなくてNumクラスのインスタンスの加法だな。
質問です。
「16文字のString型」という定義は型定義の段階でできるのでしょうか?
52 :
デフォルトの名無しさん:2008/05/19(月) 20:11:35
54 :
20:2008/05/19(月) 22:42:22
「文系」という一言でスレがこんなに伸びるとは思いませんでしたw。
ちなみに自分は理系人間に対しては羨望の眼差しで見ています。
The Fun of Programming って読んだ方いらっしゃいますでしょうか。
今日先輩にHaskellできると
彼女ができると聞いたのですが
みなさんは彼女いてますか?
>>16 そんな教科書ばっか読んでなにがしたいの?
>>20 Haskellで書かれたアプリのコード読め。
Monagiusは勉強になる。
monadiusはもはや古いぞ。
今はもっと洗練されてる。
Little Haskeller読んで学習中。日本語版もホスイ
mod_haskell.soまだー?
66 :
デフォルトの名無しさん:2008/05/22(木) 19:37:06
質問です。
0〜10までの整数を定義した型というのは宣言できますか?
>>66 data Hoge = Hoge0|Hoge1|Hoge2|Hoge3|…|Hoge10
これじゃ駄目?
数学できない奴くるな
haskell関係の文書(特に論文)を読みたくてhaskell.orgをあさってるんだけど
沢山あるからどれを読もうか迷ってしまう
このスレ的に、コレは読んでおいて損は無い!って奴あったら教えてくらはい
今のとこ読んだのはImperative functional programmingとLazy vs Strictと
Haskell vs. Ada vs. C++ vs. Awk vs. ...
Tackling the awkward squad
72 :
デフォルトの名無しさん:2008/05/23(金) 13:49:13
もうここで紹介される論文はすべて読んだんだよなぁ。
2chは時代遅れ情報しか出てこねーな。noobどもしかいねぇ。
2chの情報に価値がないと思うなら立ち去ればいいじゃないか!
>>71 落として読んでみるよー
他にもあったら是非教えてクレクレ
>>72 玄人さん面白かった論文教えて
>>69 そんな事を言う奴が来るな!
数学なんぞできんでもプログラムはできる!!
最初のうちはな
手続き型にどっぷり浸かった後で関数型言語を触って嵌ってしまったやつは
やつは皆計算機科学の世界に飛び込み二度と帰ってこなくなっちまうものなのさ
「コード書いてるより数式弄くってるほうが楽しいおwwww」
俺の同僚の最後の言葉さ・・・
だからオブジェクト指向が生き残るのですね
78 :
デフォルトの名無しさん:2008/05/23(金) 18:02:35
最近、自作のソースをarrowで設計段階からやり直そうとしているんだけど、
いまいちメリットが無いんだよなぁ。
前のコードの方が短かったし、arrowにしたせいで複雑になってしまうことも多々ある。
arrowのメリットを具体的に教えてくださいよ。
論文読んでみてもarrowのうまみが伝わってこないんだよね。
難読化
どんなものが分かりやすいかなんて人それぞれだし
arrowを使ったほうが分かりやすいって感じる人も少しはいるでしょうから
そういう人が勝手に使ってればそれでいいんでしょう
81 :
36 ◆K0BqlCB3.k :2008/05/23(金) 19:20:21
arrowを使ったプログラミングでは設計段階で図式化しやすいところにうまみがあるのかな?
ミスってコテハンつけちゃったぜ
>>78 (モナドと比較した場合)arrowの旨みって、モナドではないがarrowである型があるっていう一点じゃないの?
そういう型を扱うときはarrowの枠組みが便利というだけ
っていうかさ、俺は(\x -> (x, x))とかして処理を分けるのをいちいち書くのがめんどくさいときにarrow使うぜ
>>85 確かにそれは慣れれば便利かもな
でも、Arrow (->)という特定のインスタンスを使ってるだけなら、
>>78が言ってるようなArrowの旨味とは別の話な気がする
>>71 ちょwwBeautiful Codeって本みながら、たまたまスレ覗いたら、
本の中でソレ紹介されてたぞww
arrowって今のところ
解析関係かデバッグ関係
形式証明以外使えそうな分野
無い
分かってねーな
分かってねーなじゃわからないっす。
>>76 関数型が好きな理由は、所謂プログラミングの面白さがあるからではないな。
do { ... } は「アクションっていう値」という認識でいいの?
>>92 do構文はbind演算子で結合された式を
手続型言語っぽく見せる糖衣構文と認識してますが。
>>92 do{...}が値を持つ単なる式であるか、という質問ならそのとおり
>>93が言うようにdo式は構文糖で、bind演算子(>>=)の略記
do式の値が(広い意味で)アクションか、という質問ならそのとおり
具体的には、IOモナドに関するdo式なら値はIOアクション、リストモナドならリスト、という具合
95 :
92:2008/05/25(日) 01:35:15
>>94 >(広い意味で)アクション
の意味がわかりません。
Maybeも(広い意味で)アクションなのでしょうか?
>>96 そういうつもりで書いた
一般的でない用語法だったらすまん
Just x : なにもしないでxを返すアクション
Nothing : 計算を即座に終了させるアクション
f x: xにfを適用するアクション
1 + 2: 1と2を加えるアクション
理系の方々に伺いたいんですけど、Haskellは数学で蓄積された
知識をダイレクトにコード化が可能だと感じますか?
Cなんかだと似ても似つかないものにしないといけませんよね。
数学的なモデルのシュミレーションなんかを記述する際に、
正しく書くのは結構大変じゃないかと思ってしまいます。
そういう点で、Haskellはそのままとは言いませんが書きやすいの
かなぁと。だけど、僕の知人で理系の人たちはC言語使う場合が
多いようです。最大の理由はスピードだそうですが、手間を考えると
早い計算機使ってHaskellで書いた方がいい、という考えの人も
いるんでしょうか。
ダイレクト云々よりも
LINPACKが使えるかどうか
それが問題だ
LINPACKとか言ってるおっさん
氏ねよw
>>100 0か1かみたいな考え方は辞めた方がいいかと。
工学の人は合理的、合目的的に考えるから、適材適所でやります。
速い計算機に、さらに速いソフトウェアがあれば、より計算を回せます。
計算機が速いから、ソフトウェアは遅くていいなんてやり方じゃ、
ライバルに負けてしまいます。遊びならそれでもいいけど。
「アクション」ていうのはIOモナドだけじゃねえの?
Maybeとかでも「アクション」ていうの?
少なくともStateとかSTMモナドではアクションって言うよ
自分もActionというのはIOだけを指しているのだと思ってました。要するに
関数の外の世界に対して、関数の動きが影響を与えたり、逆の現象が発生
するのがActionであり、IO型であると。
IOがモナドなのは、モナド則に当てはまるから、ってだけではないでしょうか?
モナド則に当てはまらないものをモナドと言うわけないでしょ。
>>105 そうそう、その時点その時点でのベストを尽くします。そして、過去の仕事に対するリスペクトも忘れません。
112 :
デフォルトの名無しさん:2008/05/25(日) 15:24:57
質問です
たとえば
data Hoge = Hoge { x1 :: Word32, x2 :: Word32, x3 :: Word16, x4 :: Word16}
のようなHogeを[Word8]と相互変換する便利な方法ってないでしょうか?
使ったことないけどSerTHとか?
>>113 へえ・・・ 何となくおもしろそう
ドキュメントとか読んでみます
SerTH見てみましたけれど、どうやら私の用向きとは違うようですね。
Template Haskellの方もちょっと見てみます
計算理論の基礎
計算機プログラムの構造と解釈
ってどっち買ったらいいの?
なんか最近数学の基礎たりねー
ちなみに計算理論の基礎が
つい先日第2版が出たので聞いてみた
私事だけど金がないので優先度が欲しい
後者は原著がネット上で無料で読めるから前者
というか全然違う傾向のほんのどっちがいいか聞かれても…
しかもHaskellには関係ない
推薦図書スレは別にあるよ
全く調べずに聞くが、concurrent arrowなんてのは無いの?
arrow使ってていつも思うんだが、並列処理に向いてなくない?
FPGAとかのHDL記述とかに応用したりしてる人いないの?
>>117 若いうちに読んどいた方がいいのは計算理論の基礎 の方だろ。
計算機プログラムの構造と解釈は仕事で必要になってからで十分。
>>123 独学でやってしまった奴は
次何すればいいの?
とりあえず今自習でλの数学側の
側面勉強してみているが
何の役に立つかわからん
僕が「ラムダ計算は知っておいたほうがいい」と思う理由は、形式的計算体系としての“純粋ラムダ計算”が理論的に重要だから、というだけではありません。
むしろ、次に述べるようなことがより大きな動機となります。
まず、関数を表現する方法としてのラムダ記法(lambda notation)に慣れて、紙と鉛筆によるインフォーマルなラムダ計算が出来ると、
けっこうそれを使える場面が多いのです。例えば、「JavaScriptによるテンプレート・モナド、すっげー簡単!」の最後で、モナド法則を示すために、
インフォーマルなラムダ計算を使っています。
ある種の計算的実体(例:クロージャ)や計算手法(例:継続ベースの計算)の説明にもラムダ式がよく使われます。
式言語(EL; expression language)に対する処理系(パーザーやエバリュエータ)を作る場合なども、ラムダ計算が良いヒントになるでしょう。
もちろんラムダ計算は、既存の関数型言語を理解する基盤となります。あるいは、新しいプログラミング言語を設計する際にもラムダ計算が規範になるかも知れません。
そもそも計算とはいったいなんなんだ?
後者関数ってなんだぉ?
やっぱ手書きしねーと理解できねーよw
data type Nat = O | S Nat
という定義で自然数(0以上の整数)が表現できる。(ペアノの公理を満たす)
このとき S のことを後者関数(successor function)と呼ぶ。
ここで
定義に再帰を使っていいんですか?
とか聞くとYコンビネータとか出てきちゃうんだろうか
質問です
yampaっていったい何ですか?
ごく簡単に馬鹿でもわかるように概要を説明してください
Yampaってコンパみたいなもん?
「The Haskell School of Expression」で使われているコードの
ファイルってどこかに落ちてませんかね。
>>138 あ、これってグラフィックライブラリだけじゃなくて、本のコードも
入ってるのか。勘違いしてた。ありがとう。
comb :: Maybe a -> (a -> Maybe b) -> Maybe b
このときの
Maybe a -> (a -> Maybe b) ここまでが入力だよね?
2項目の引数が関数になっているって解釈でいいんだよね?
うん
違うだろw
入力 : Maybe a
出力 : (a -> Maybe b) -> Maybe b
()でくくるとどうなるのw?
>>142 同じことじゃねーか
関数を返す関数と二引数の関数を同一視するのはHaskellでは普通の習慣
>>143 a -> Maybe b
っていう関数を引数にとるっていうことだよ
>>140 Maybe a -> (a -> Maybe b) の2つを入力とする事もできるし、
Maybe a だけを入力とする事もできる。
後者の場合は(a -> Maybe b) -> Maybe bの関数が出力となる。
これを部分適用といい、こういった事ができるのが
Haskellの魅力である。
…と認識しています。
>>145 えっとねそれじゃあ
Maybe aと関数を引数に取るために
(a -> Maybe b)、この2つを与えてますよね?
関数渡すためにこう記述するしか方法がないから
そのようになっていると理解したてみたのですが
どうやら上の人曰く間違っているようで何が違うのでしょうか
Haskellはグラフ簡約によって1度に1つのTermを解釈していくだけ
なので、最終的な結果は高々1つになるはずだと思っていたのですが
どうやら違うようで混乱してきました。困った、不勉強だ困った
>>143 右結合の二項演算子?である「->」の結合順序をデフォルトから変更している。
A -> B -> C -> D
は、「->」が右結合の二項演算子?であるがゆえに、
A -> (B -> (C -> D))
と解釈される。
A -> (B -> C) -> D
は、
A -> ((B -> C) -> D)
と解釈される。
>>147 >どうやら上の人曰く間違っているようで
間違ってないよ
>>147 > Haskellはグラフ簡約によって1度に1つのTermを解釈していくだけ
> なので、最終的な結果は高々1つになるはずだと思っていたのですが
> どうやら違うようで混乱してきました。困った、不勉強だ困った
型の問題と適用の問題が、頭のなかでうまく区別が付いていないのでは?
適用される関数はA -> (B -> C) -> D型で変化はないけど、
* A型の「値」に適用すると、(B -> C) -> D型の「値」(関数)が帰ってくる。
* A型の「値」と、 (B -> C)型の「値」(関数)の2引数に適用すると、D型の「値」が帰ってくる。
このように考えてはどうか。
これで納得できなければ、やっぱり単純に、
A -> (B -> C) -> D型は、A型の値をとって、(B -> C) -> D型の値を返す関数の「型」
という出発点に戻るべきかな。
>>142が突っ込んでるのは
> Maybe a -> (a -> Maybe b) ここまでが入力だよね?
の部分。
> 2項目の引数が関数になっているって解釈でいいんだよね?
こっちは合ってる。
カリー化とは何か?を書いた方がいいんではないでしょうか。
↓ではお願いします。
この関数適用は出来損ないだ。食べられないよ。
カリー化とは、
複数の引数を持つ関数を
引数一つの関数の組み合せとする事。
…と認識しています。
カリー化という言葉を見ると頭の中で
「カリンカカリンカ カリンカマヤ」という歌が繰り返されて止まらなくなる。
おれもそうりかいしてる。<154
でも、カリー化ときいてターメリックをぶっかけてるイメージしかないw
ガラムマサラとかも入れた方がいいのでは?
エバラ化、桃屋化
味の素化
>>140は
A -> (B -> C)
というふうに切り出してしまったけど、これは本来の
A → ((B → C) → D)
という結合関係を無視してる(「A -> (B -> C)」という型を扱うみたいに書いている)。
ってのが
>>142でしょ。
カリー化の影響として、「複数の引数をとる」
(A × (B → C)) → D
ことと、「関数を返す」ことの、どちらに主眼があるかが不明瞭になるってのがあると思うね。
>>151>>160 その理屈は分かるんだが、カリー化を理解してるのか怪しい初心者に対して
混乱させるようなことを言うのは不親切だと思う
Maybe aと(a -> Maybe b)の二つが引数になっているという理解で正しい、と教えれば十分じゃないか
f(a,b,c) = y
f : A×B×C→Y
f a b c = ((f a) b) c = y
(((f a) b) c) : Y
((f a) b) : C→Y
(f a) : B→(C→Y)
f : A→(B→(C→Y))
> Maybe a -> (a -> Maybe b) ここまでが入力だよね?
「ここまでが引数リストに対応する部分だよね?」と読むと○
「ここまでが引数の型だよね?」と読むと× ← ちょっと窮屈な解釈かも、みたいな空気
> Maybe a -> (a -> Maybe b) -> ここまでが入力だよね?
と書けばおk
なるほどw
複数引数の邪悪な関数をこらしめるのがカリー化です。
それだけならタプルで渡せばいいだけじゃそ
:
=>
これがよくわからん
<コ:彡
兄者…
>>168 :は、リストの先頭に要素を結合する演算子
=>の左辺(文脈)は、
多相的なデータを静的型チェックするために
コンパイラに与える条件
…と認識しています。
だれかもうちょっと正しいコメントを付けてやってください。お願いします。
[1, 2, 3] ← ふつうの見やすい表記(ただし、本来のデータ構造が見えない)
1 : [2, 3]
1 : 2 : [3]
1 : 2 : 3 : [] ← 本来のデータ構築子 (:)(cons)、[](nil)で書く(ただし、いまいちリストに見えない)
1 : (2 : (3 : [])) ← 右結合性にたよらないで書く
(:) 1 ((:) 2 ((:) 3 [])) ← 演算子としての表記法をやめる(S式マゾ以外には読みにくい)
お願いします m(_ _)m
Haskell実用経験皆無の俺が来ましたよ
>>168 4.1 Overview of Types and Classes
> but the type system has been extended with type classes (or just classes)
> that provide a structured way to introduce overloaded functions.
型クラスの存在意義がわかるかどうかだと思う。
整数の足し算と有理数の足し算って、ふつう同じ記号を使うけど、
計算の内容は違う(多重定義、オーバーロードされている)でしょ。
でも、共通の性質を考えたいときもある。
そのとき、ただ「共通の演算記号+を使っているから同類とみなす」では話にならないから、
twice :: a -> a
twice x = x + x -- 2倍したいけど、+の型などがコンパイル時に不明
+を「Numという型クラスの特徴」として整理して、整数や有理数はその特徴を共有している、とみなすと。
twice :: Num a => a -> a -- 「型aはクラスNumに属する(Numのインスタンスである)」という前提をする
twice x = x + x -- と、演算子+の存在と型が保証される
そんな感じ?(ごめん、確認してない)
改めて見るとオーバーロードの解釈が破綻してるなw
すまぬ
=>
C++のテンプレートの特殊化みたいなものか
演算子は定義されているけど特定の型じゃないと
処理できない場合、特定のの変数を特殊化すること
あるけど
Haskellian ももうブランドではなくなりましたね…
メジャーになった証か
=> の意味は総称型に制限を与える、じゃだめなのかなぁ。
質問、というより興味本位のアンケート。
あなたが思うhaskellの面白いところってどこですか?
アホな質問するスレがあるところ
堅い言語なのに簡潔に書けるようになってるところが面白いと思うし、すごく好きだ
記号を多用してたり、インデントを使ってたり
「haskell使ってる」と言うと、みんなに尊敬して貰えること
>>180 高速化を考え出すと、すごくたいへんなところ。
185 :
デフォルトの名無しさん:2008/06/05(木) 21:02:04
[(x,y) | x + y = 10]
知らない人は知らないし、知ってる人はわかるもんな
しかしいい言語だ
汎関数系の言語はC++もそうだが、
かなり野心的な言語設計になるね。
クラス囲い込み度が低いからだろうか。
>>185 そんなのできたの!?と思って ghci で試したらできなかった。
ちょっと悲しくなった。
インデントがよくわからなくて
エラーでていらつく
なんとかならんのかね?この糞言語
インデント制約糞なら最初からなんか
そういう機能入れろよなぁ
あーあー世界で最悪の糞言語だね
インデントのせいだけで
>>190 そういう説もあります。
そうでないという説もあります。
インデントがいやなら { } と ; で全部区切ればいいじゃん
一緒だよ
traceの使い方qsortのサンプル使って
教えてくれませんか?
qsort _ [] = [] (1)
qsort f (x:xs) = before ++ (x : after) (2)
where before = qsort f (filter (not . (f x)) xs) (3)
after = qsort f (filter (f x) xs) (4)
どこにいれればいいのやらw
それを見つけるのにもtraceが役立つのではないか
>>193 私はまだtraceに手を出すつもりはありませんが、
ググってみました。
参考になるでしょうか…?
↓
第15回 Haskellでのデバッグのコツをつかむ
ttp://itpro.nikkeibp.co.jp/article/COLUMN/20071204/288630/?P=2 import Debug.Trace
quicksort[] = []
quicksort(x:xs) =
trace ("x." ++ show x) $
trace ("x." ++ show x ++ " > y." ++ show losort) $
trace ("x." ++ show x ++ " <= y." ++ show hisort) $
losort ++ [x] ++ hisort
where
losort = quicksort [y|y <- xs, y < x]
hisort = quicksort [y|y <- xs, y >= x]
Main> quicksort [3,2..1]
x.3
x.2
x.1
x.1 > y.[]
x.1 <= y.[]
x.2 > y.[1]
x.2 <= y.[]
x.3 > y.[1,2]
x.3 <= y.[]
[1,2,3]
[(x,y) | x <- [1..], y <- [1..], x+y = 10]
>>196 これ、やってみたけど止まりませんね…。
*Main> take 10 [(x,y)|x<-[0..],y<-[0..],(x+y)==10]
[(0,10)
x=0 のままyの無限リストを検索してるから当たり前ですけど…
*Main> take 10 [(x,y)|x<-[0..],y<-[0..]]
[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9)]
↓みたいなリストを返す簡単な方法ありますかね…?
[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2).....]
こんなもんかな…
tlist::[(Int,Int)]
tlist = concatMap (\n ->f n) [0..]
where f = \n->take (n+1) $ iterate (\(x,y) ->(x-1,y+1)) (n,0)
*Main> take 10 tlist
[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2),(3,0),(2,1),(1,2),(0,3)]
*Main> take 10 [(x,y)| (x,y)<-tlist, (x+y)==10]
[(10,0),(9,1),(8,2),(7,3),(6,4),(5,5),(4,6),(3,7),(2,8),(1,9)]
つまらない答えだが
[(x,y) | k <- [0..], x <- [0..k], y <- [0..k], x + y == k]
つまらないのならこれが一番
[(x, 10-x) | x <- [0..10]]
[(a,b) | x <- [0..], y <- [0..x], x + y == 10, (a,b) <- [(x,y), (y,x)]]
こんなんできたっけ
なんだ(a,b)って t <- [(x,y), (y,x)]
>>202-203 なるほど、そういう事もできるのですね。
*Main> take 12 [t | x <- [0..], y <- [0..x], (x+y)==10, t<-[(x,y),(y,x)]]
[(5,5),(5,5),(6,4),(4,6),(7,3),(3,7),(8,2),(2,8),(9,1),(1,9),(10,0),(0,10)]
リストモナドの>>=はconcatMapでしたもんね。
勉強になります。
(5,5),(5,5)がだぶってるのが、おしいですね。
GHC 6.8.3 まだー?
無明関数って何がうれしいの?
いちいち関数の名前考えなくても良い
名前をつけるまでもない単純な関数を作る時に便利
名前を付けることは名前空間を汚染すると言うこと
名前よりも式そのもののほうが理解しやすい場合もある
getChar >>= \a -> getChar >>= \b -> putChar b >> putChar a
こういうのに名前つけるのはいやだな
>>208 そういう話題は関数型言語スレのほうが向いている。
関数型言語一般について語れるよ。
>>208 どんなバックグラウンドをもってる?関数型言語についての経験は?
手続き型の国の人ならば、わかりにくいところやね。
関数を変数でもたすってのは関数型では日常茶飯事なんですわ。
そこに便利さのヒントがアルよ。
map (\(a, b) -> a+b) [(1,1), (2, 3) ..]
>>213 手続きの国からワープしてきたのですが
関数を変数にするならポインタ渡せばよくないですか?
そうすれば、定義しても渡せますよね?
名前があってもなくてもポインタ渡すのです
関数オブジェクトは、メソッドがひとつしかないクラスのインスタンス、に似ています
インスタンスに名前がついているとは限らないのです
>>216 よくわからないぉ
もう少し詳しく説明してぉ?
無明関数…悟りでも得たいのか?
名前を考えるのが面倒くさい
再利用しない
定義している箇所を探すのが面倒くさい
関数内部の処理が簡潔
のときは無名関数使いたくならないか?
つーか、関数本体そのものずばりを一覧できる状態で渡しているのにわざわざ名前をつける必要があるのだろうか
カリー化
(new Satori(x)).open(y)
無名関数で再帰するにはどうすればいいですか
たとえば、
f n = if n == 1 then 1 else n * f (n-1)
はどのように書けばいいですか?
fix (\f n -> if n == 1 then 1 else n * f (n-1))
むみょーん。Haskellian じゃないから fix があるかどうかシラネ
型無し言語なら
(\f -> f f) (\f n -> if n == 1 then 1 else n * f f (n-1))
あー、でも f って名前つけちゃったな
>>225 Control.Monad.Fix にありますね。
fix :: (a -> a) -> a
fix f = let x = f x in x
>>224 不動点演算のfixを使うようです。
Prelude> Control.Monad.Fix.fix(\f n -> if n == 1 then 1 else n * f (n-1)) 5
120
(\y f -> f (y f)) (\y f -> f (y f)) (\y f -> f (y f)) (\y f -> f (y f)) ...
>>224 ... f ...
where f n = if n == 1 then 1 else n * f (n-1)
局所的な関数定義で代わりになるんじゃないの、というのはダメかな
名前が付いてるからダメ
... (f where f n = if n == 1 then 1 else n * f (n-1)) ...
こうかー
>>235 whereが作るのは式じゃなくて節だから使える場所が決まってる(定義の後とかcase選択肢の後とか)
... (let f n = if n == 1 then 1 else n * f (n-1)) in f) ...
ならおk
閉括弧が一個多かった
... (let f n = if n == 1 then 1 else n * f (n-1) in f) ...
239 :
デフォルトの名無しさん:2008/06/16(月) 14:44:56
ポイントフリースタイルについて質問なんですが、
Haskellでは原理的にどんな関数でもポイントフリースタイルに
変形可能なのでしょうか。
うん
>>239 Sコンビネータとかもポイントフリーに出来るんだっけか?
どの範囲の関数まで使用を認めるかによるな
>>241 Control.Monad.ap :: (Monad m) => m (a -> b) -> m a -> m b
を(->) rモナドについて使えば、Sコンビネータそのもの
243 :
デフォルトの名無しさん:2008/06/17(火) 22:58:00
ポイントフリーのポイントって何?
何が自由なの?
ポイント = initial objectからのarrow
ポイントフリースタイル = ポイントを使わない関数定義
(Monad m) => m (a -> b) -> m a -> m b
これって未だによくわからないけど
手計算できそうな実例ないですか?
あんまり意味ないけど↓こんなのとか?
f :: Monad m => m (a -> b) -> m a -> m b
f mg mx = do { g <- mg; x <- mx; return $ g x }
test1 = f Nothing (Just 1)
test2 = f (Just succ) (Just 2)
test3 = f (Just id) Nothing
test4 = f [] []
test5 = f [id] [5]
test6 = f [id, succ, (* 2)] [6, 9]
GHC 6.8.3リリース
ナイス
>>244 initial object(始対象)じゃなくて terminal object(始対象)だお。
集合の圏で terminal object からの arrow というと一点集合に相当する。
集合の圏では任意の一点集合 x に対して f x = g x ならば f = g
「point(一点集合)を使わずに関数が等しいことを表現できる」=>「ポイントフリー」ということだと思う。
>>249 失礼、書き間違えた。
terminal object(終対象)だな。
251 :
249:2008/06/18(水) 18:26:24
× terminal object(始対象)
○ terminal object(終対象)
だった。
俺やべぇ
気がついたらポイントフリースタイルで5行も書いてたぜ
これはもはや関数型スパゲッティだな
任意のλ式はSKコンビネータで書き換えられるとか言うのを見て
実際に適当なλ式で変換してみたら出てきた式はとても読める
代物ではなかったのを思い出した
ありゃ一種の難読化だよな
>>253 SKコンビネータも、名前付きにできると若干読みやすそうだけど。
っていうか、それが出来たら、どんな高級言語とも変らんという話になって、逆に面白さがないか。
以下の関数fをもっと簡単にする方法ありませんか?
f [] = []
f (_:[]) = []
f (x:xs) = (x, head xs) : f xs
簡単に、というより再帰を使わずにできませんか?
f xs = zip xs (tail xs)
f xs = zip xs (drop 1l xs)
262 :
261:2008/06/23(月) 19:03:55
すまん。tail の l を残してしまった。
f xs = zip xs (drop 1 xs)
zip [] ⊥ = []
らしいから
>>260と
>>261は等価かな
こういうのを意識しないといけない場面だと非正格性が気持ち悪い
いやむしろ tail で書けて気持ちいいだろ。
>>265 でも
zip (tail xs) xs
と
zip (drop 1 xs) xs
は等価じゃない
つまり、zipでは第一引数が先に評価されるということを覚えていないといけない分、ややこしい
(厳密には評価順の問題じゃなくて「zipは第一引数について正格で第二引数について非正格」ということだけど)
267 :
デフォルトの名無しさん:2008/06/24(火) 07:48:57
>>266 どういうこと?
例えば
f (x1 : x2 : x3 : xs) -> x1 + x3
だったら、引数のリストの最初の要素と3番目の要素について正格ってこと?
>>267 そういうつもりで「正格」という言葉を使った
関数結合の(.)って優先順位が高いので、
どうしても括弧が増えて見ぐさい気が…。
こんなのがあったら便利だと思うんですけど、
↓
infixr 1 $.
($.)=(.)
こんな感じ
↓
sigma = tail $. scanl (+) 0
標準ではなさそうなんですが、
やっぱ、問題ありですかね?
慣れの問題
ああ、勘違いしてました。
関数の優先順位はどの演算子よりも上ですね。
これで問題ないのか
↓
sigma = tail . scanl (+) 0
>>270 レスありがとうございます。
早く慣れたいです。
まだ、頭で考えないとよくわからない。
(考えてもわからない時ありw)
>>266 > 覚えていないといけない
覚えてなくてもプログラム書くのにはなにも困らない。
等価性とか考えだすと全部正格のほうが楽かもしれんけど。
>>273 書くときは良くても読むとき困る
例えば
>>260のコードが空リストに対しても正しく動作するかどうか確かめるのに、
いちいちPreludeの仕様を読まないといけない
zipみたいに明確な定義のある関数ならまだいいけど、
例えばhPutStrLn undefined ""の値が
1. ⊥
2. 実行時にエラーになるアクション
3. ()を返すアクション
のどれになるかは仕様では決まっていないはずで、ちょっと厄介
>>274 その辺は想像で読めば十分じゃない?
zip xs (tail xs) とあって、
コードを書いたのが信頼できる人なら、
zip は第二引数について非正格なのだろうな、とか。
hPutStr undefined "" も、
hPutStr _ "" = return () と定義されては無いだろうし、
undefined が正しいハンドルじゃないからと
hPutStr が独自にエラーを出すというのも、
先に undefined が評価されるから有り得ないだろう、とか。
hPutStr (error "1") (error "2") にしても error "1" だろう、とか。
ム板のやつらはなんでこんなに視野が狭いんだろうといつも思う。
3の場合
main「ちょっと undefined に "" 出力してこい」
hPutStrLn「へい」
...数十ns後
hPutStrLn「やってきやした」
main「おまwwww改行どうしたwwwwwwww」
>>276 正直くだらないネタ以外はここではなく他の所に書く。
質問です
HaskellでGPGPU関連の話題ってありませんか?
279 :
274:2008/06/25(水) 20:23:02
すまん、hPutStrLnじゃなくてhPutStrじゃないと話が合わないな
>>275 >コードを書いたのが信頼できる人なら、
勉強のためにコードを読んでるならいいけど、
レビューとかデバッグとかしてるならそうはいかないだろ
>hPutStr が独自にエラーを出すというのも、
誤解させたかもしれんが、HugsもGHCも2.の振る舞いをする
実行した時点でundefinedが評価されてエラー発生ね
でも、例えば最適化のために
hPutStr h s = seq h $ ...
みたいな実装になってたら1.だし、
hPutStr h s = mapM_ (hPutChar h) s
みたいな定義が考えられる以上3.もあり得なくはない
結局、非正格がデフォルトなせいで関数の仕様に書かなければいけない事項が多いのが問題
それを不用意にうやむやにすると関数の振る舞いが実装に依存してしまう
それほど頻繁に問題になることではないけど、たまに面倒
280 :
275:2008/06/25(水) 21:28:51
>>279 > レビューとかデバッグとかしてるならそうはいかないだろ
うん。
> hPutStr h s = mapM_ (hPutChar h) s
> みたいな定義が考えられる以上3.もあり得なくはない
なるほど。
> それほど頻繁に問題になることではないけど、たまに面倒
そういうこったね。
281 :
275:2008/06/25(水) 21:32:14
> 誤解させたかもしれんが、HugsもGHCも2.の振る舞いをする
> 実行した時点でundefinedが評価されてエラー発生ね
そういうつもりでしたか。
ちなみにそれだと1.はどういうつもりだったのですか?
>>281 hPutStr undefined "" `seq` 0
を評価してエラーが発生すれば1.だよな
実際試したらHugsでもGHCiでもエラーは発生しなかった
283 :
275:2008/06/25(水) 22:26:04
なるほど。というか
>>279をちゃんと読んでませんでしたごめんなさい。
一通りよく取り上げられる教科書は読んだんですが、Arrowなどの
比較的新しい技法についてわかりやすく書かれた文書はどの辺
でしょうか。
本家から辿って論文を読むのがいいと思うよ。
Arrow アーーー
arrowねぇ・・・イマイチだねぇ・・・
プログラミング的にはこれといってメリットないよ。
arrowで量子コンピュータのシミュレーションやってます
めっちゃべんりですっっっっs
ユニタリ変換の理解が一つの山かも。
ユニタリ変換?高校生でも知ってるよ
皆さん、エディタは何使って書いてますか?
emacsしか選択肢ないんじゃね?
eclipseは糞だし。
vim
notepad.exe
vimやemacsだと使い勝手のいいプラグインあるんでしょうか。
自分もEclipseはちょっと嫌ですねぇ。
Haskellの構文解析ってどういう風な作りになってるん?
結合性宣言があったりするので、
トークン読んだ時点では構文木を作れないような気がするんだけど。
何かの資料とか、HugsやGHCでの実現方法のソースとかあったら教えてくだしあ
>>298 GHCはとりあえず全部左結合として解析(parser/Parse.y)して、
後のrenameのパスで結合性宣言をもとに組み立て直してる(rename/RnExpr.lhs)
>>292 俺もvimだわ
なんか文法と相性良さげだし
>>299 そういう手があったか。いや、全然関係ないパーサを先日作ってたんだが。
パス(1パスコンパイラとか2パスコンパイラとかのパス)にこだわっていては
非富豪的かねぇ。
左結合にするってのは、
とりあえずリンクトリストにしといてから、
あとでパーズしなおすって事。
>>292 俺はAgda使ってるよ。結構使いやすい。
project eulerに接続できねーぞ!!!
どうなってんだ糞
質問です
グラフの研究で路線データ(や道路のデータなど)が使いたいのですが、
そういうデータを手に入れるにはどうすればいいですか?
>>305 質問です
Haskellと関係ありますか?
307 :
298:2008/06/28(土) 22:27:19
>>299,302
thx、参考になった。
細かく追えてないけど、かなりがんばらないとparseできないってことか。
とりあえず左結合って要するにS式だよね。
後の兜本である。
オライリーからHaskellの本が出るなんてありえない。
そう思っていた時期が僕にもありました
2008/09
ちょおまw
>>310 全30章中残りは3章。
20. The foreign function interface
27. Profiling and tuning for performance
30. A concurrent RESTful web application
書きにくそうなのが残った感じw
初心者用のスレで関数型の話をすると罵られる。なぜだろう。
初心者には関数型が高尚すぎて理解できないからです。
しつもんです
らむだけいさんってなんですか?
世界遺産の一種です
全部ひらがなだとぱっと見、人名かなんかかと思った。羅武田圭さんとか。
俺がムラタだ
まあ遅延評価だから
等無駄計算
>>322 なにエラソーに言ってんだよ。しょーもない評論家なくせして。
名村啓?
do記法で
'aとか''aとか出てきますが
どのような意味なのでしょうか
329 :
デフォルトの名無しさん:2008/07/21(月) 15:09:50
>>327 a'とかa''じゃなくて?
ちなみにそれならただの変数名だよ。
>>329 見直したらそうでした
許してくださいw
ごめんなさい
\_ -> k
この\_ってC++のtemplate <t>みたいなもんですか?
全然違います
なんか夏まっさかりって感じ?
質問の仕方スレもいるな
Haskellでぐぐっていくつか読めばわかるぐらいのことで
これって型でしょ
違います
じゃあなんなんだよ
つ やさしいHaskell入門
おい、おまえらの仲間が「初心者のための〜」スレで暴れてるから早く回収してくれ
狂犬に噛まれて狂犬が増えるって
怖くね?
あれは仲間じゃない
そもそもスレタイからして興味ない話だし。
向こうで完結して。
さて、この夏、何かおもしろいことでもしようかな。
お前らの中にアホがいます
他のスレを荒らすならここを荒らしますよ?
>>342 ほー、やってみてください。本当にできるのですか?
夏厨誕生物語
A 「この夏、何かおもしろいことでもしようかな。」
B 「ならスレ荒らししてみれば?」
A 「簡単にできるのですか?」
B 「こうやれば邯鄲」
A 「ネ申キター!d!マジ面白いね。他スレ荒らしてクルーwktk」
仕事でHaskellできるなんて羨ましいなぁ。
349 :
デフォルトの名無しさん:2008/08/06(水) 20:47:23
ハイカラなシャツ着てる
この会社ってホームページ見た感じ普通のSI会社に見えるけど、
山下さんなんかがいるってことは特殊な会社?
Haskellの開発コンサルということだけど、一般企業の業務システム
なんかを対象にしてるのかな。金融系とか合ってそうだけど、
普通の土方システムには豚に真珠かな。
>>350 看板役みたいなものだよ。
よくあること。
SRAでも青木淳みたいなのを雇っているけど、青木は普通の仕事はしていないね。
金にならないことを自由にやっているって感じ。
ちなみに、青木の部下はかわいい女の子限定。
まあ、天才ならなんでも許されるってことだ。
>>345 nobsunのコードは以前からスゲーと思ってたけど、こんな会社のこんな人なんだ。知らなかった。
会社の事業だけ見ると、Haskell関係なさそうだね。Higher Order Programmingってなんだ?造語か?
もっと記事をよく見てみる。
Higher Order Programming: プログラミングを丸投げするためのプログラムを書くこと
357 :
デフォルトの名無しさん:2008/08/07(木) 09:45:57
継続ベースのWebフレームワークってHaskellにもありますでしょうか。
>>350 あそこって、gaucheかんけいなひとがおおそうなんだけど。
>>358 そりゃそうだ。普通のJaverやC++マが金を取ってこなきゃ、
みんなgaucheとかに走ったら誰が食い扶持を稼ぐんだって。
二等兵には二等兵の仕事があるわな。
むしろ、パンダと飼育員。
俺はまだ士官候補訓練兵だ
あの写真を見て
小野伸二を思い出したんだけど。nobsunはやっぱり天才なんですかね。
俺は山田ルイ53世を思い出した。すまん>nobsun
ルネッサ〜ンス!
あの芸人、この前番組内であからさまにいじめられてたぞ。
最近テレビの前で普通にいじめる先輩芸人が多くないか?
366 :
デフォルトの名無しさん:2008/08/07(木) 19:55:17
そんなことより「Real World Haskell」の発売が10月に延びてる・・・
最近少しずつ読み進めていたんだが
そうか、本になるのか…買おうかな>RealWorldHaskell
RealWorldHaskellってHaskellの批判本なのに
なんでみんな買うの?
こんなにHaskellって腐ってます
ゴミですって随所に書かれているのにw
買おうかなと言ったのが一人いるだけなわけだが
脳内カウンターが回りまくりですかな
ん?批判本なんだ?
そう思っている人がいるかどうかは定かではないですが、
そう書き込んだ人間が一名いるようです。
また、買おうかなと書き込むことと買うことは別です。
プログラマたる者、このくらいの論理性は持って欲しいです。
部分と全体を混同するなんて、継承に毒されすぎです。
>>372 論理じゃなくて、揚げ足取りっていいませんか?
買おうかなと書き込んだということは、買う意思が比較的強いということでしょう。
0か1かじゃないんですよ。
物事は確率的なのです。
>>373 > 買おうかなと書き込んだということは、買う意思が比較的強いということでしょう。
著作権者や出版社勤務者が宣伝のために書いたかも知れませんよ
>369
>Throughout this book, we're going to show you how Haskell's
alternatives to the features of traditional languages are more
powerful, more flexible, and safer. Haskell is positively crammed
full of cutting edge ideas about how to create great software.
(chap1 power)
と最初のところでかいてるけど、なぜ批判本と?
どこをさしていってるの?
なんとなくpractical common lispのhaskell版と言う印象なんだけどな。
オレイリーから関数型言語ぼんが出るのは初めてじゃ内科?
国内ではgauche本があるがね。
フランスではocamlの本が出てた
380 :
デフォルトの名無しさん:2008/08/08(金) 11:58:00
washって継続ベースなの?
感覚的には日本のRubyと同じ感じじゃないすかね。
>>381 いつの本の話してんだか。
この本の和訳プロジェクトはつぶれたね。
>>382 全然違う。Rubyは世界的にPythonを急追している。
急追して、、いたけど結局ダメだった、というのが現在のところだよ
俺も1.9がちゃんとしたモノになるまではrubyは使うべきではないと思う。
386 :
デフォルトの名無しさん:2008/08/08(金) 23:59:16
そうか?
そもそも本当に10月に発売できるか分からんぞ。
コレすでに3回発売日伸びてる
年内出れば御の字
>>385 それがほんとかなぁ。とおもってgoogle trendsでruby,python,perlの検索数を比較させて
みたけど、国によって微妙に違うね。
usaなら、2006ねんごろからperlが凋落しきって、python,rubyとならんで、2006中頃から、
rubyが一歩抜けて、perl,pythonが同等になっていた。
italyは、同じような時期にperlが落ちてきてるけど、pythonがかなり強くって、perlとruby
が同等
japanが、perlの凋落が進んできてるけど、usaやitalyほどではなくて、一番ですね。2番め
がrubyで徐々に増えてる。pythonは完全に横ばい。
chinaはpythonの伸びがかなり強い。そんなにrubyは使われてない。
indiaは日本と傾向が似てるな。
israelはrubyは絶滅ぎみ。
google全体ではrubyが一番強くなってきてるけど、これはusaでのruby人気が支えてる
ような感じだな。europaとchinaではpythonが強く、それ以外の国ではperlが強いかな。
>>384 世界的にみても、わかって言語を選んでいる人よりも
バズワード追ってるだけの人のほうが多いからね。
Haskellって本当にLLって言っていいのかな。
基本コンパイラだし、インタプリタも軽量とは言い堅いし。。。
LLじゃないだろw
> 基本コンパイラだし
GHCばかり取り上げられてHugs涙目
>>392 そんなあなたをはぐはぐ。w あーっ!ではないよ。
初心者なんですが、Haskellが型については静的であることを選択した
理由って何かあるんでしょうか。純粋であることや遅延評価が、静的
型やコンパイル時の最適化を要請するということなんでしょうか?
GHCはHaskell解釈系ランキング第一位!
「やっぱりGHCだね」
>>394 静的なのは、最適化も大きいだろうけど、
むしろ安全性を狙ってるという要素が大きいんだろう。
遅延評価なのはコンパイル時の最適化にプラスなのかなぁ?
これは理論的に停止できる関数は必ず停止できるっていう、
これまたある種の安全性?が主な目的だと思うけど
( if true (answer foo) (nonStop baa) ) みたいな文を考えよう(Haskellの文法忘れたから適当)。
別に"動的型付け-純粋-非正格-インタプリタ型"の関数型言語もあり得るよな
効率はどうなんだろう、"動的型付け-正格"の言語よりさらに遅いことは想像が付くが
>>394 Goferがそうだったから。
で、なんでGoferがそうだったのかというと、Mirandaがそうだったから。
>>396 遅延評価は最適化にマイナスだよ。少なくともメモリ空間の最適化には全く向かない。
遅延評価なんて
今日はやらない
401 :
396:2008/08/09(土) 10:50:37
>>399 そうだよね。
コンパイル技術がすげー発達して高速になれば、話は変わるだろうけど。
(まぁ、コンパイル技術が「すげー発達」すれば、どのコンパイル言語でもマシン語と同じスピードが出るんだから、意味ない話)
あと「理論的に停止できる関数は必ず停止できる」は意味不明だとか、
文じゃなくて式だとか、気づいたけど後の祭り、いわゆるアポステオリorz
>>395 Guarded Horn Clauses
手続き型言語は、ノイマン型計算機を抽象化することで生まれてきたので、
評価方式としては、式、文の逐次的解釈が当然になる。
関数型言語は、ラムダ式から出て来たから、
その評価形式をどうするかというのが一つのポイントになる。
遅延評価は最左最外簡約の研究から出て来た。
効率がどうのこうのというより、
新しいプログラミングパラダイムを産み出したので、
(例えば無限リスト、無限木の積極的利用)
研究され続けているんだと思う。
関数型とか意味がない言語だと思うけどねぇ
何ができるってわけでもないし
HaskellでWindowsは作れないしLinuxも作れない
Webサーバも作れないしDBも作れない
意味がない
ごめん、今からインディージョーンズ見に行くから急いでるから!
まあ普通はモデルを現実に合わせるよな。
代入だらけのプログラムをSSAとかいう形式に変換するとか。
>>394 純粋関数型言語・遅延評価で、
型なし・インタプリタ言語ってあるよ。
変態言語 Lazy K がそれ。
ある意味では Make とかもそうかも。
少なくとも、
純粋関数型言語・遅延評価と、
コンパイル言語かインタプリタ言語か
っていうのはあまり関係ない。
純粋関数型言語・遅延評価は、
シンプルな手続き型よりもインタプリタを書くのが難しい、
っていうのはあるかもしれないけど。
純粋関数型言語であることと静的型であることは、少し関係があるかも。
純粋関数型言語でかつ動的型というのは、概念的にあまり良い食い合わせではないとは思う。
動的型っていうのは、関数の世界では「型無し」ってことになると思うんだけど、
いずれにせよアドホックなエラー処理が必要になって、
純粋関数型的にアドホックなエラー処理というのは少なくとも美しくない。
>>409 遅延評価でインタプリタ。破壊的関数が作れないというものなら、R言語くらいしか知らない。
411 :
394:2008/08/09(土) 12:56:14
皆さんレスありがとうございます。
論理的に組み合わせ悪いというよりは、静的型のメリットを選んだ
ということなんでしょうか。
静的型VS動的型というのは、安全VS自由ということだと思うんですが、
Haskellは安全を選んだということなのかな。純粋関数型としては、
副作用に関連する不具合から自由なのが売りだと思うので、更に
静的型によって徹底的に信頼性を上げてるという感じなんでしょうか。
>>409 純粋関数型であること(参照透明であること)と動的型が食い合わせ
悪いというのがちょっと分かりませんでした。動的型は実行時不具合
の問題が付きものと思うのですが、参照透明との関係をよろしければ
少し詳しく教えていただけマスでしょうか。
そもそも関数型言語に意味が無い
>>411 動的型を使うと、アドホックなエラー処理が必要になるよね?
っていうか、それがないと動的型を使ううまみがないと思うんだけど。
ここでいうアドホックなエラー処理っていうのは、
対象オブジェクトの型をプログラムで認識して、
意図しないオブジェクトが来たときにエラー処理するってことだけど。
このエラー処理にIOを使わないなら、
それは多相型やクラスを使っても同じ結果が得られるよね。
だから、Haskellに動的型を組み込む必要性は、
意図しないオブジェクトが来たときIOを使ったエラー処理をしたいときに限られると思う。
で、純粋関数型言語は参照透明性ゆえにIO処理するの苦手。
まぁ、動的型っていうのはプログラム中で型を認識できないと意味ないよね?
っていう時点で、カリー・ハワード対応との関係で微妙っていう気にするけど。
僕が考えているのは、そんな感じ。
上っ面を語り合って自己満足か
Haskellに多いやつらの典型だなw
グリーンスパンの第10法則が発動すると、どんな言語で書こうと
動的でマルチパラダイムな言語で書いたのと同じになる。
416 :
394:2008/08/09(土) 13:33:07
>>413 なるほど、理解しました。ありがとうございます。
>>416 implementationの本を読むといいよ
Peyton Jonesのがpdfで読めるはず
>>418 俺はPJのが好きだな。
静的型付けとグラフ簡約が運命的な出会いであることがわかった。
>>413 なんか議論が無茶苦茶じゃないか?
例えば「型エラー」を「0除算エラー」に置き換えても論理展開が変わらん
>このエラー処理にIOを使わないなら、
>それは多相型やクラスを使っても同じ結果が得られるよね。
動的型の重要な利点は、型をいちいち書かなくてもいいという利便性だよな
多相型やクラスを使って動的型をシミュレートするのはすごく面倒だから、この利点を享受できない
それから、GHCではerrorやundefinedで発生したエラーをIOモナド上で捕捉できる。念のため
だな。Haskellの例外処理で不足があることはそうそうないと思う。
あと、動的型のメリットを例外処理だけに限定するのは視野が狭すぎる。
LISPのメリットはアドホックな例外処理か?そうじゃないと思う。
>>420-421 納得できないのなら、それで良いです。
僕も、べつにそんなに優れた論拠だと思ってないから。
本当だ、マジで何言ってるのかわからん
すげえ
425 :
394:2008/08/09(土) 15:22:47
動的型のメリットは型を単に書かなくて済むことだとは思えないんですが。
それだけであれば、コンパイルで発見する不具合をテスト時に見つけよう
とする、つまり面倒なことを後回しにしてるだけ、ってことになりませんか?
別に動けばいい
何でも指せるポインタってのはメチャ便利なんですよ。
S式なんて最たるもので、静的な型付けは不能あるいはワイルドカード的。
静的か動的かはトレードオフの問題。
>>425 不具合を見つけるタイミングが遅くなるという対価を払って、記述の利便性および変更の容易さという報酬を得る
ちゃんと取引として成立してるじゃないか
もちろん「型を書かなくて済む」こと以外にも利点はある
特定の静的型付け言語ではそもそも型を付けられないようなコードが許容されるとか
>>425 lispを使ってる限りの印象だが
都合のよい所だけ型宣言が出来るというのは柔軟性につながるかな。
プログラムの最適の仕方も静的/動的で違いがあると思うよ。
型なんで考えずにアルゴリズムだけ作っちゃえができるからね。
それでも型を意識したプログラミングをすることはあるが。
でも、haskellでもポリモつかえばある程度型無視ラピッドプログラミング
は可能じゃないか?
じゃあOCamlでいいじゃん
>>430 haskellって参照透明性ってかなりのメリットだと思ってるけど。
注意してかけばいいだけの話
Hashkellはメリットを殺すデメリットしかないだろ
>>430 OCamlはstrictだから。残念。
435 :
394:2008/08/09(土) 19:55:26
>>428 コンパイル時に問題が抽出されることと、テストによって抽出されるのでは
質的な違いがあるんじゃないですか?テストは結局は人間がやるものだし、
不具合の可能性を低めるということにしかならないけど、コンパイルでの
不具合検査は対象となるプログラムの論理的正しさを証明していることに
なるかと思います。
容易に変更ができたとして、不具合がどこに潜んでいるのか分かりにくい
というのは非常に問題あると思いますよ。コンパイルで分かるのならば、
これは明白でしかも機械的に全てが晒されますから安心です。
Rubyは危険だしセキュリティリスクしか
そんざいしないしな
>>435 確かに、バグがどの段階で発見されるかには質的な違いがある
でも、静的な型検査だって全てのバグを検出できる訳じゃないから、
結局、動的検査との安全性の違いは程度問題
その上で、静的な型検査の利点がコストを上回るという判断は当然ありえるし、
そう判断したなら静的型言語を使えばいい
439 :
394:2008/08/09(土) 20:39:50
>>437 例えば、参照透明ということについてはどうでしょうか?こちらも、副作用を許容
すれば、プログラム中に登場する変数の中身が何に変異しているかどうかが
分からなくなり、実行してみないと問題が検出できない、ということになります。
参照透明を強要するのも、型を強要するのも、結局その辺がクリアできない
プログラマというのはそれらに関連する不具合を出してしまうんだと思いますが
どうでしょうか。気をつければいい、というのは簡単で規模が小さなシステムでは
言えることで、そうでなければ膨大なテスト工程が必要になってしまうのでは?
OCamlが参照透明じゃないから嫌ってどういう事を言ってるの?
refとかで破壊的な変数が作れるから嫌とかそういうレベルの話じゃないよね。
それだったらref使わなければいいだけだから。
逆に、Haskellの参照透明で良い所ってどのへんなの?
OCamlのでも、ErlangのでもなくHaskellの参照透明性が良い理由を説明してほしいんだが。
441 :
394:2008/08/09(土) 21:04:32
>>440 参照透明でない、ということは値が望んだ通りの値であることを
保証するためにどこまでも神経質にテストをしなければならない、
ってことですよね。
一人で開発するのであればいいですが、多くの人の手によって
間違いがあってはならないシステムの開発をする際、「それは
禁じ手だから止めてね」と口約束するだけってのは非常に怖い
わけです。だからこそ、テストの工程が膨れ上がる。
Haskellに自分が惹かれている大きな理由の一つは、この辺の
頑固さを貫いていることですね。
参照の透明性があれば、
それだけでテストが必要なくなるわけでも、
テストが簡単になるわけでもない。
そうなるのはトイプログラムだけ。
嘘だと思うなら、GHC, Hugsなどのバグトラックをみてみればいい。
テストが減ることを数学的に証明してみせれ。
444 :
437:2008/08/09(土) 21:22:55
>>439 何が言いたいのか良く分からん
俺は「気をつければいい」なんて一言も言ってないよ
>>428に書いたように、動的か静的かの間でトレードオフが成立すると言っているだけ
>>441 OCamlの変数は変更不可だよ
変更できるのは参照(ref)で、これは変数とは別物
だから、口約束するまでもなく変数の値が変わらないことは保証されてる
>>440 参照透明性を壊さないと入出力できないのが嫌
>>443 数学的に無理だから、統計的に証明するわけですよ。
実際に〜〜でした、ってね。
ヒューマンインターフェース系の論文が参考になるんじゃないかな。
あっちは全部そんな感じ。
>>441 Haskellでもやろうと思えばIORefとかで事実上破壊的な操作が可能になるわけですが、
これについてはどうお考えで?
「HaskellでIORefは使うな」っていうプログラミングルールを設定することは
「OCamlでref使うな」っていうルールを設定することと本質的に違わないと思うんだけど
それについてはどうなんすか。
インディージョーンズ、あれは予算が無いからあんなにちゃっちい水晶髑髏なのか?
どう見てもアクリル製のガワの中に反射板入れただけやん。
UFOとかエイリアンとか、考古学じゃなくてSFやん。
突っ込みどころ満載な映画でした。
かしこ
monadとラムダの簡単な練習いっぱい
したいです。どこがいい問題集頂戴
>>449 do記法を使わずにliftM、liftM2、joinを実装
Continuationモナドを実装
そんなことが書きたいんじゃなかった。
>>419 PJのって何?本もpdfもPJのでしょ?
>>453 >>449は本当にモナドとラムダの練習のためだけに問題をほしがっているのかどうかってこと。
それに、初心者は何か目に見えて動かせるものを書きたがるものさ。
誰かに見られることを想定して書くのと、「動けばそれでいい」だけで書くのとでは、
やっぱり前者の方がいろいろ調べたりすることで勉強になる。
載ってるよー
グラフ簡約と運命的な出会いというと遅延評価じゃないかね。
特にPJ的には。
461 :
419:2008/08/11(月) 14:41:51
>>460 まあグラフ簡約は前提として、それを効率的に実装するには静的型付けがイイんだよ、
と、約20年前に読んだ時に思った。
462 :
419:2008/08/11(月) 14:44:37
20年前じゃなくて15年前だった。かなり記憶が混乱してるな、俺 orz
>>461 あまり理解できてなかったんじゃない?w
>>463 かもしれない。
できれば君が読んでポイントだと思ったところを挙げてくれると皆の参考になると思う。
PJの最初の本だと、
例え動的型チェックをやろうとも、そのコードは、
他の普通のコードと一緒でスーパー・コンビネータになって、
グラフ簡約されるだけだから、コンパイル時に型チェックを済ませることが、
スーパー・コンビネータのグラフ簡約上、特に有利だとは思えません。
横から口はさんですまんが、静的型がついていたほうがパターンマッチが速くならね?
467 :
デフォルトの名無しさん:2008/08/13(水) 09:02:33
Haskellの継続ってSchemeとは違いありますか?
call/cc のようなものはありません
>>468 MonadCont の callCC :: ((a -> m b) -> m a) -> m a のことじゃないの。
>>467 俺も気になる。違いはあるだろうけど、どう違うのか。
470 :
デフォルトの名無しさん:2008/08/13(水) 11:23:16
やっぱりそうですか。継続ベースのアプリ
作るとしたら、ステートモナドに次のアクション
入れておくとかですかね。
MonadContだと、型の関係で、無限ループするような式は書けない。
# mfixとか使えば別だけど。
例えば、Schemeで次の式は書けるが、MonadContでは書けない。
(call/cc (lambda (c) c))
(call/cc (lambda (c) (set! foo c)))
つまり、次の式は型が付かない。
callCC (\c -> return c)
callCC (\c -> lift $ put c)
要は、callCCで捉えた継続をそのcallCCの外に出せない。ただし、
callCC (\c -> ... callCC (\c' -> c c') ...)
のように、内部で別のcallCCを使って、それで捉えた継続を外に出すのはOK。
あと、変な例として、
callCC (\c -> return (Right (c . Left)))
はOK。でもやっぱり無限ループはできない。
>>471 だとすると、smlのcall/ccを使ったco-routineみたいなことはできないということ?
smlのcall/ccを使ったco-routineは知らないけど、co-routine自体はできる。
import Control.Monad.Cont
foo = callCC (\c0 ->
do
c1 <- callCC c0
c2 <- callCC c1
c2 10
undefined)
bar =
(do
c1 <- foo
c2 <- callCC c1
callCC c2)
main = print $ runCont bar id
>>471 HaskellでYコンビネータを書くとき型が問題になるけど、
実質的には fix f = let g = f g in g で問題ない。
それと同じように、
loop = callCC (\c -> let g = c g in return g)
とすれば
do { l <- loop; liftIO $ print 0; l }
のように無限ループを書ける。
(これの変数付きループ版が MonadLib にあった。)
(call/cc (lambda (c) c))
がどう使われるのかよく分からないけど、
実質的には同じことになるんじゃないかな?
(call/cc (lambda (c) (set! foo c)))
callCC (\c -> lift $ put c)
は IORef を使うと問題なくできる。
State だと無理だけど、新しく再帰的なデータ型を定義してやれば、
あまり便利では無さそうだけど一応できた。
オラ本の執筆遅れてます
著者にプレッシャヨロ
どうせ買わないので暖かい目で見守るだけです。
Schemeのcall/ccってその時点の継続を勝手にキャプチャして渡してくれる
んですよね?Haskellではそういうのは無いと思っていいんでしょうか?
>>477 モナド無しでということなら無い。
そもそもcall/ccは副作用があるし。
あれはモナド有りでの話だよ。
山本モナド
コメント欄も読もうな
487 :
デフォルトの名無しさん:2008/08/17(日) 13:44:52
>>443 >>446 静的で強い型を持つ言語は、単純な実行時エラーを防ぐので
テストは軽減する。haskellなどはそのことが数学的に証明されているので
プログラマはぬるぽやoutofboundsなどの基本的な間違いにであうことなく、
本質だけを考えることができる。
パターンマッチに失敗すること多くない?
たとえば「空でないリスト」型が欲しいとき、ぬるぽ的な実行時エラーを防げるの?
ぬるぽは無いけどout_of_bounds発生させまくりですが
依存型のある言語なら防げるかも知れんけど
>>487 おまえ初心者スレにいたHaskell信者だろ。
はいはい両者リングアウト
モナドがIOに使えるのは分かった。けどどうしてそれをIO以外にも使ってるの? >Haskell
誰か教えて下さい
Maybe(笑)を証明するため
便利だから
どんな時に便利ですか?
498 :
497:2008/08/17(日) 19:11:05
第 II 部:標準的モナドのカタログ
の各モナドの利用場面や動機を見るのもいいかもしれない
一応リストモナドやMaybeモナドが計算に使える、というのは理解しているつもりですが、
便利だからという理由以外にモナドをIO以外に使う理由はあったりしますか?
それだけの理由で使うには扱いが難しくて、プログラムを組む度に頭がオーバーヒートしそうになる
慣れの問題かそれとも理解不足か・・
モナドという抽象的な枠組みを考えることで
IO, Maybe, List, etcの計算の合成を統一的に扱えるってのが最大の利点なんではないかと。
単に使うだけなら主に慣れの問題だと思う。
いろんな例を見て慣れていけば少しずつ理解もできていくんではないかと。
自分の作ったモナド上でdo式を書くと、世界の法則を書き換えてるような気分になってちょっと面白い
>>501 レス有難うです
慣れの他に密度の問題もあるかもしれないと思ったり。
他の言語より1行あたりの密度が濃いものになりやすい気がする。
というか濃縮されすぎてわけが分からなくなりやすい気がする。
>>501 計算を統一的に扱うだけであれば、普通の型クラスでいいんですよね?
モナドは値ではなくて型コンストラクタに対するクラスなので、ちょっと違う
と思うんですが。
モナドっていうと仰々しいイメージがあるかもしれないけど、
所詮はただの代数的データ型とそのデータ型に対して一貫性あるAPIのセットに過ぎないよ。
ところで、 データ型とAPIのセット のことをなんて呼べばいいの?
Stateモナドとかの(s -> (a,s))みたいな変な定義が気持ち悪い
型クラス(b,s) -> (a,s)に型bを部分適用したって考えれば意味は通るけど……
>>505 それが「型クラス」、ではないのでしょうか?MonadやFunctorはちょっと
毛色が違うという認識は勘違いでしょうか?
それ単にOrdとかの『類』は*で引数をとらないけど
Functorの『類』は*->*みたいに引数をとる、って違いにしか見えない
分けて考えるのはおかしいと思う
>>509 型クラスと型構成子クラスじゃ抽象度が違うよ。
俺も
>>509みたいに感じるなあ
抽象度が違うのは理解できるが
512 :
507:2008/08/17(日) 21:58:16
抽象度の違う型クラスを持つことで、値の計算遷移とは別レベルの
遷移を持つことが可能だ、という印象を持つんですけどどうなんでしょうか。
普通の計算を行う裏側で別の次元での計算が行われ、且つそれが
結合法則を満たしている、というのがモナドの定義と考えるのは
どうですか?自分は圏論などのこと全く無知なのでHaskellの構文
からの直感的な印象だけなんですけど。
じゃあ類が*->*->*(関数(->)とかタプル(,)とか)に対する型クラスとかは
もっと抽象度が違うので別の名前が必要なのか?型構築子構築子クラスとか。
有名な人が書いてるから鵜呑みにしてるだけなんじゃないの?
>>512 だいたいあってんじゃね?
見えてる部分で適当に処理を書いたら裏で適当に処理してくれる、
普通のプログラミング言語じゃfor文やif文みたいな処理構造、
あるいはマクロとして提供されるものと同等の処理ができるんだけど、
実態は単に型クラスでしかないので俺定義できるし、高階関数使えるし、表記もシンプルで、いろいろ小細工が利くのが利点。
たとえば、IOみたいにコンストラクタを隠したりすれば脱出不可な構造を作れるってわけ。
結合法則を満たしているってのは、まぁ別に特別なことじゃない。
EqやOrdにも反射律とか推移則とか守らないといけないルールがあるけど、
よっぽどのことがない限り変な実装はしないだろうから、一般のプログラミング言語ではそこまで突っ込まない
でもモナドって実態がよくわかんないから、ルールを明記してる。そんだけでしょう。
念のため補足。
>処理構造(略)同等の処理ができるんだけど
普通の言語では処理構造のものが、モナドが利用されてる例としてはErrorモナドとかContinuationモナドとかがあったね。
>よっぽどのことがない限り変な実装はしないだろうから、一般のプログラミング言語ではそこまで突っ込まない
浮動小数点の比較と等価性で違う実装がされてるとか、変な実装もあるけど。
個人的にはMonad則は、
値に関して順次実行できる何かで、値に対して何もしない処理もできる何かだ、というルールだと解釈してる。
変な実装=全順序じゃない、と読み替えてくれ。
コンピュータのメモリ節約を考えれば生の浮動小数点型を使うのもまっとうな実装だわw
ごめん、誤解を招くといやなのでもう一つ補足……
>値に関して順次実行できる何か
これは実行順序じゃなくて値の計算する方向を言ってるだけだよ。
g.f x がxにfを適用してgを適用するってのと同じことだよ。
実行順序は普通のモナドもIOモナドも方向は決まってないよ。
ん?
実行順序を明確にするのがIOモナドの目的の一つ
と認識していますが。
そういう意味ではないのかな…
Haskellをみて日本のhaskellコミュって元気なの?
他の言語に比べて内と外をわけすぎるようなそんな印象をもってる。
なんでだろ?
>>518 たとえば、
1:2:3:[]は、
1:2:3:[] → 1:2:[3] → 1:[2, 3] → [1, 2, 3]と簡約されるかもしれないし、
1:2:3:[] → [1, 2:3:[]] → [1, 2, 3:[]] → [1, 2, 3]と簡約されるかもしれない。
でも結果は一緒でしょ?
同じように、
Hello, Worldって出力 >> 一文字入力 >>= 前の文字を出力
みたいなのは、まぁ言ってみれば(不正確だけど)
[Hello,Worldって出力, 一文字入力, 前の文字を出力]みたいな並びにされる(と思われる。実装はカプセル化されていて不明)。
この並びがプログラム終了後にコンパイラにわたって、コンパイラがこれを順番に処理していく。
実はこの並びをプログラム終了後以外に評価する方法があって、それがUnsafePerfomedIOって言う関数。
getContentとかは実はこれを使って実装されている。
Unsafeという名前が示すように、素人にはお勧めできない。(getContent自体は普通に使える。)
Maybeの特化にしか見えません
>>519 世界的に全く元気がありません。
ちょこっと変なライブラリを書いたと思えばそれっきり離れていっている人も多数。
>>520 後者の簡約は型がおかしいし、1:2:3:[]ではなく、
f x = (unsafePerformIO $ print x) `seq` xで
f 1:f 2:f 3:[]だった場合、前者と後者の簡約順序ではprintの順番が違ってくる。
前者は3,2,1で後者は1,2,3
一方で(>>=)は最左最外簡約でも最右最内簡約でも
左から順にしか値が定まらないようになってる。
putStr "Hello" >>= (\ _ -> getChar) >>= (\ c -> putChar c)
(>>=)の右辺が関数だから左辺の値が定まるまでa >>= bが最終的な値に簡約できないようになっている。
>>522 元気無い理由って何でしょうか。他に元気ある言語ってあるのかな。
ruby
>>520 > 1:2:3:[] → [1, 2:3:[]] → [1, 2, 3:[]] → [1, 2, 3]と簡約されるかもしれない。
型が滅茶苦茶だよ。
> この並びがプログラム終了後にコンパイラにわたって、コンパイラがこれを順番に処理していく。
意味不明。なぜプログラム終了後にコンパイラが出てくる。
ランタイムライブラリとごちゃまぜになているぞ。
527 :
デフォルトの名無しさん:2008/08/18(月) 10:05:00
Haskellにこういう奴が多い気がするのはなぜだ
「こういう奴」と書けばどんな奴を指してるのか分かってもらえると思ってるような、
想像力の貧しい奴がこのスレに多いような気がする
末尾が「気がする」で終わってるレスは
全部気のせいのような気がする
なんという自己言及レス
関数型らしくて言いじゃないか
* -> * -> * ってどんなとき使うの?
アナルトレイン
( ゚д゚)゚д゚)゚д゚)
/ つ つ つ
(_(_ ノ ノ ノ
し∪ ∪ ∪
>>505 > ところで、 データ型とAPIのセット のことをなんて呼べばいいの?
プログラミング言語一般での話なら「抽象データ型」でしょうね。
485でおま。
それでなのです。 >ときどきの雑記帖の中の人
Arrow は * -> * -> * のクラス
MonadTrans は (* -> *) -> * -> * のクラス
本買えよ
30章だけが読みたいんだよ。
ところで、HaskellでPetStoreってあるの?
>>542 横からすみませんが、
Pet Storeをよく知らないのでちょこっと検索したんですが、
これっていったい何が面白いんですか?
>>543 面白くは無いんだけど、色んな言語やフレームワークで同じもの作る
ことで比較をするためのものでしょ。同じアプリがこんな感じで作れ
ちゃうぞ、という。
Haskellでウェブアプリというとふつう本か
最近では新しい言語はWEBアプリが書きやすくないと人が入ってこないらしく、
ライトウェイト言語がブームみたいだね。
HaskellはライトウェイトではないからWEBアプリ向きとは全然思えないんだけど、
RubyでRubyOnRailsが考えられたみたいにHaskell独自のWEB向きキラーアプリが
出てこないとHaskellの人気はこれからもずっと平行線だと思うよ。
>>546 WEBアプリが書きやすいっていうより、APIとかWEBコンテナが標準装備されてないとダメという感じがする。
Javaの功罪は大きい。
まだ横ばいならたいしたもんだ
>HaskellはライトウェイトではないからWEBアプリ向きとは全然思えないんだけど、
ライトウェイトって何?動的に型を付ければライトウェイト?
それとwebとどういう関係があるの?
あまり考えずに気の向くままに書いてもあっさり動くのが
ライトウェイトってことじゃないか?
web案件は短期だったりアジャイルだったりでライトウェイトに
開発できるのが求められてるってのはある
WEBアプリの開発者は、JavaかRubyのHowto本から入ってる。
だから、WEBアプリ開発者は、身体のどこかに、プログラミング言語のJavaかRubyに似てない部分に拒否反応を持ってる。
ここでHaskellは人間の思考過程に最も近いから
考えが即座にコードにうつせるため開発期間が最短であると主張する人がどこからか登場
↓
|
( ゚д゚ )↓
(⊃⌒*⌒⊂)
/__ノ''''ヽ__)
>>550 それならHaskellもライトウェイトで良くね?
明示的なコンパイル作業が必要ないってのはLLの必要条件な気がする。
LLとかWebアプリとか、
だから普及しないとか、
どうでもよくねえ?
好きな事、楽しい事すればいい。
>>555 runghcがあるじゃないか
もうちょっと速ければと思うことはあるけど
>>556 そういう立場も理解できるけど、俺は普及してほしい
ライブラリのメンテとか人が足りてないじゃん
runghcはオーバーヘッドもかなり大きいみたいだね。
$ cat hello.hs
main = putStrLn "hello"
$ time runghc6 hello.hs
hello
real 0m0.835s
user 0m0.780s
sys 0m0.052s
$ cat hello.rb
print "hello\n"
$ time ruby hello.rb
hello
real 0m0.015s
user 0m0.012s
sys 0m0.000s
$ cat hello.pl
print "hello\n"
$ time perl hello.pl
hello
real 0m0.007s
user 0m0.004s
sys 0m0.000s
$ cat hello.py
print "hello"
$ time python hello.py
hello
real 0m0.035s
user 0m0.020s
sys 0m0.016s
LLでHaskell関係のプレゼンとかしてる人いるみたいだけど?
WebアプリとLL(と呼ばれている言語)との間には全く関係はないけど、
Webアプリのかなり大部分は一般的にLLと呼ばれている言語で書かれているだろう。
そういう"LL"はテキスト処理がしやすいからってのがあるだろうな。
まあHaskellがそういう意味で人気にならなくても別にどうでもいいけど。
ここでmondic Parser Combinatorを持つHaskellが
最もテキスト処理に適した言語であると主張する人がどこからか登場。
↓
HaskellもLL言語だよ
Parser Combinatorがあるからテキスト処理ならHaskell最強だろ。
満足した?
haskellは型推論がちゃんと効いてる使い方が出来れば、LL的な生産性は確保できるだろう。
だがな、至高の存在で良いじゃないか。
haskellの性質上webプログラミングは不得意分野に思うんだが、mod haskellなんて生まれる
分けでもないし生まれたところで破壊的操作がほとんどできないし、ファイル操作は基本的に
苦手でしょ。webは動的言語の親玉が一番向いてるけどs式アレルギーな人が多いからLLに
なってるんでしょうね。
だから、無理にwebに擦り寄らずとも良いと思うんだけどね。むしろ、破壊的操作より安全性を
大切にされる金融などのところで目立つ存在になってくれたらいいんじゃないか?
>>567 もし金融などで使われることを想定するなら、
haskellの並列処理に関する部分も早く実装してほしいところですね。
(まだ未完成)
某氏のhapps解説はお流れ?
>>567 > 破壊的操作がほとんどできない
なんで?
なんでそんなにHaskellの応用分野を限定したがるんだw
>>567 コンパイルするならmod_haskellがあっても恩恵は小さいだろ
>破壊的操作がほとんどできないし
Haskellで入出力書いたことあるか?
>ファイル操作は基本的に苦手
これも良く分からん
flock使うのにわざわざライブラリを落としてこないといけないとか、そういうこと?
ウイルス対策ソフトのように危機感を煽るのはいいが、
既存のシステムを補強するのではなく全部作り直せというのは、ちょっとね
>>570 Prologを事務処理に使うと、住所や氏名情報などで爆発的にアトムが
発生し、Heap領域を埋め尽くして、GCが頻発するという事態となる。
もちろん数百万レコードを越える処理単位の話だが。
Haskellの場合この問題は起きないの?
Webアプリが苦手ってことは無いと思うんだけどな。今後Webベースのアプリは
まだ増殖するだろうから、そっちで使いやすいフレームワークやDSLが出ないと
使う人は頭打ちだと俺も思う。
研究者の論文レベルのものも面白いだろうけど、上から下までHaskellベースで
かかれたWebアプリとかで目立つものが出てほしいよ、個人的には。
>>572 アトムの爆発ってのはPrologスレで言及されてる現象のことでいい?
そもそもPrologのアトムってのが良く分からんので何が問題なのか理解できん
Lispのシンボルみたいな物と思っていいのかな
それなら相当するものはHaskellにはないよ
>>574 Lispのシンボルみたいな物、ですね。
記号をどう処理しているのですか。
576 :
デフォルトの名無しさん:2008/08/22(金) 21:53:05
>>575 「記号」と言われてもいまいちピンと来ないんだが、何にせよ、
普通の手続き型言語が「記号」を処理するのと大差ない方法で処理してると思う
取り得る種類がコンパイル時に決まっているなら列挙型
そうでないなら整数とか文字列
文字列の比較のコストが問題になるなら自分でシンボルテーブルのようなものを用意する、とか
>>572 Prologでも、
1レコード512バイトをsub_atomで30項目に分解したり、更にsplitの
処理をしたりすると確かにアトムが大量発生するだろうが、
Stringとして読み込んで、終始String処理に徹すれば、アルファベットの
数、つまり高々数万のアトムで済むんじゃないの?
Stringすなわちリスト処理になると遅いから嫌なのかな。
宣言的言語をリアルタイム処理に使いたくない病にかかってる。
資源が十分にあると理屈では分かっていても、終わったら電源切っても大丈夫な処理じゃないと拒否反応がでる。
>>579 処理速度もあるかも知れませんが、アトムだと、
foo([株式会社|R],R).
と書けるところが、Stringだと
foo(List,R) :- append("株式会社",R,List).
と書かなくてはならないということがあります。
appendを高速化する機構が欲しくなりますね。
それって代数的データ型を使ってこんな感じで良いんじゃない?
data Atom = Kabushiki | Dummy deriving (Show, Eq)
foo :: [Atom] -> [Atom]
foo (Kabushiki : r) = r
>>581 この話おかしいよ。
foo([株式会社|R],R). の方は、
すでに株式会社というアトムが切り出されていて、リストの構成要素になっている。
一方、
foo(List,R) :- append("株式会社",R,List). のListはString。ここは、
foo(["株式会社"|R],R).
でなきゃ、フェアじゃない。
>>572 > Prologを事務処理に使うと、住所や氏名情報などで爆発的にアトムが発生し
第五世代コンピュータプロジェクトの成果を是非参照下さい。
>>585 よく知らないけどソフトウェア科学会会誌7月号に第五の話題が載っていたよ
成果って、「prologって役立たずじゃん」という結論を得たこと?
>>587 それは短絡的な人たちの根拠のないうわさ。
第五は基礎研究なので企業の人たちが求めるような成果が出ないのは当たり前のこと。
Prologの話は他でやってくれ
んで問題点を整理してまたいらっしゃい
詳しいことは忘れたけど、
述語論理による仕様記述を使った鉄道のプロジェクトが企業側で行われた例があったような。
なんだったっけ?
Prologはどうでもいいのだが、Haskellで金融(とくに保険業)のアブリを
開発する場合、何か問題になる点はないのか。
>>591 必要なメモリサイズを予測しにくい点とか。full lazyな処理系全般に言えると思うけど。
金融系システムにHaskellを使うメリット自体が思いうかばん。
いいじゃん、Javaでつくるのが流行ならJavaで作らせれば。
どうせ枯れたシステムなんだから。
>>592 full lazyな処理系って、よくわからない。
どんな言語で書いたとしても、必要なメモリの量は実際に動かしてみないとわからないよ。
haskellっていいプロファイラあんの?
>>595 COBOLなんかは確定してると思うけど。
>>597 してない。
SORTなどに内部的に使う記憶容量が不明。
Haskellのようにデフォルトで遅延評価する言語は、
計算をできるかぎり遅延させようとするから、
下手な書き方するとすぐメモリリークする
Haskellのメモリリークは大抵の場合小規模な修正で直るけど、
どこを修正すべきか探すのに慣れとプロファイラが要る
>>596 GHC付属のプロファイラは優秀だと思う
>>596 profオプションをつけてコンパイルしたらランタイムシステムにプロファイラが組み込まれるよ。
詳しくはマニュアルで。
>>598 ん?確定はしてなくても最大どれかけかかるかは確定してるでしょ。
グラフ簡約のヒープ消費は予測もつかんぞ。
Haskellでメモリーリークが起きるのですか?
ガベージコレクションにバグがない限り、
メモリーリークが起きるとは思えないのですが…。
FFIを使った場合の事でしょうか…。
これも「メモリーリーク」と呼ぶのでしょうか?
*Main> foldr (+) 0 [0..1000000]
*** Exception: stack overflow
プログラマが意図してないで、リファレンスが残るようなコーディングを
しちゃってる、というのをリークに含めることもある。
stack overflowが発生する時、
簡単にわかる場合は「マヌケ」
ちょっとわかりづらい場合は「メモリーリーク」
と呼ぶという認識でよろしいでしょうか?
リークってのは「漏れ」のこと。
GCのある言語だと、
>>606しか起こり得ない。
>>605の「溢れ」とは全然違う。
>>605 それはスタックオーバフロの例外であって、エラーとは違う。
メモリリークしているわけではないよ。
C言語みたいに型があいまいな言語ではメモリリークが起こりうるが、
Haskellみたいに強い静的型付けされている言語にはメモリリークなんてありえないよー
スタックオーバーフローとメモリーリークは
現象として全然違うと言う事ですね。
分かります。
>599や>604が挙げているような例はC言語で
良く言われる「メモリーリーク」とは違う現象だな。
Haskellの場合、遅延評価がデフォーなので
うかつに再帰を使うと計算の途中結果が膨大な
ものになってヒープ領域が溢れてしまう。
Cの場合はただの確保したメモリの解放し忘れ。
Cでも再帰的なメモリー確保をすれば
Haskellみたいな事も起きうるはずだが。
>>611 強い静的型付けとメモリーリークの有無はほとんど関係がありません。
GCの方がずっと関係が深いです。
Pascalのnewとfreeだっけ?
あれ考えれば分かるよな。
強い型付けでも簡単にメモリーリークは起きる。
foldl でも stack overflow するんだよね。
Data.List.foldl' 使えばいいんだけど。
なんで foldl でスタック溢れるの?末尾再帰が最適化されてないの?
>>604のリンク先に書いてある
末尾再帰は最適化されるよ
620 :
617:2008/08/24(日) 00:40:37
>>618-619 なるほど、非常によくわかりました。
(つーか前出のリンク読まずにレスして申し訳ない)
うーむ、しかし末尾再帰が最適化されることの旨みは、
・ローカルスコープの値をスタックに積む必要がなくなることと
・連続するreturnが省略されること
の2点だと思うけど、foldl のように結局は遅延評価のための
computation がスタックに積まれていて、後から順次簡約するなら
「最適化されている」とは言い難い気もするな・・・。
最適化するための然るべき変形は、一応してあるんだろうけど。
まあ seq 使うとか、回避の仕方がないわけじゃないからいいのかな?
「特にErlang」…
実用性でいうとやっぱErlangなのかな…
>623
大規模なWebサービスを構築するのに向いていると
考えたから企画者がErlangを採用したんだろうね。
大規模な、ってのがクセ者で、
実情は単にDBのテーブルが大きいだけだったりするよな。
そもそもウェブアプリでDB以外どこが肥大化するよ?
626 :
デフォルトの名無しさん:2008/08/25(月) 09:11:28
画面?
>>625 複数のwebサービスから情報集めたり、もしくはhttp以外のプロトコルで通信して情報を取得しなきゃいけなかったり、
別プロセスで並列キューに入れて処理しなきゃいけなかったり、システムそのものが大きくなるとこはあると思う。
それともデータサイズの規模に限定した話?
>>625 とりあえずErlang + YAWSの事例くらいは、
念頭においてくれないと、話にならないのでは?
>>627 > 複数のwebサービスから情報集めたり、
そういうのはAjaxでクライアント側がやるのが流行では?
まあサーバ側がやってもいいですが、HTTPセッションを入れ子にするのは
あまり筋がいい設計とは思えません。
> もしくはhttp以外のプロトコルで通信して情報を取得しなきゃいけなかったり、
まあDB接続なんかもそうですよね。
しかし「大規模になる」ような要因とはあまり考えられないのですが。
> 別プロセスで並列キューに入れて処理しなきゃいけなかったり、
fastcgiとかの話でしょうか?特段、だから大規模になるというものではないと思いますが。
> それともデータサイズの規模に限定した話?
コード自体はほとんどCMS系フレームワークをユーザ定義コンテナを定義する程度で
用が済むことが多いと思います。特に、
>>622のような、いかにもCMSっぽいシステムでは。
>>629 > コード自体はほとんどCMS系フレームワークをユーザ定義コンテナを定義する程度で
> 用が済むことが多いと思います。特に、
>>622のような、いかにもCMSっぽいシステムでは。
よいCMS系フレームワークを、
容易に開発できるかどうかって話をしているんだと思いますよ。
>>630 なるほど、わかりました。
格納するコンテンツの量は結局DBのサイズの問題になると思うので、
それ以外の「大規模」の要因というと、
・同時接続数(パフォーマンス)
・登録ユーザー数
ぐらいでしょうか。
それとも単純にコードサイズを指して「大規模」という話なんでしょうかね。
「学校」というドメインが明確になっているので、
一般のCMSフレームワークほど汎用化は要求されないし、
どのような要因でコードサイズが「大規模」化するのか興味があります。
>>624 Apacheとか使わずErlangでサーバー構築するんじゃないの?
キッチンシンクアプローチか……
Erlangをわざわざ使うということは、数百レベルの並列プロセスを
マルチコアで何とかしようと考えていると見て間違いない。
Webだとすれば、WebServer以外考え難い。生徒数千でほぼ
同時にアクセスがあるとか。
しかし、
>>622 はなんでErlangスレに書いてないんだ?w
単に初期メンバーにErlang使いが居ただけなじゃいの?
Erlangスレ見たことない方ですねw
Erlangはどうでもいいんだけれど、
HaskellでもPerl使いを確保しておいて、単体の機能は専らCPANから取り出させて、
確保されているインターフェイスを介してHaskellで利用するというやり方は
多くなるんじゃないかな。短時間で開発する一手法としてね。
ならないね。
>>638 落日のPerlを使うかどうか。 規格書の通りに一からすべて開発するのは確かに大変だね。
Text/ParserCombinators/ReadP.hsとKoen Claessen氏のペーパーを読んで思ったんですが、
Haskellに慣れてくるとこの実装が直感的に見えてくるんですか?
Haskellのパーサコンビネータ関連のペーパーを読んでいない状態でReadPを読んで、
data P a = Get (Char -> P a)
略
| Result a (P a)
略 なのを「え、一番直感的じゃん」
とか、
newtype ReadP a = R (forall b . (a -> P b) -> P b)
で
instance Monad ReadP where
return x = R (\k -> k x) ← これとか
fail _ = R (\_ -> Fail)
R m >>= f = R (\k -> m (\a -> let R m' = f a in m' k)) ← これとか
とか
get = R Get
ってなるを、「ああ、自明だなすげえ直感的」みたいに理解できるようになる物なんですかね。。難しすぎる。。。
>>629 大規模になる要因なんていくらでもあるじゃん。
今時は単にUIがWebで、バックエンドが複雑化してるものも少なくないしね。
分散業務システムで多種類のプロセスを相手にすりゃ自然と規模は大きくなるかと。
何でもかんでもインターネット上でパブリックに利用可能な整理されたサービスばかりじゃないからね。
学校だって企業並みにシステムが複雑化してるとこもあるから、強ち単純とは言えないんじゃないかと。
まあ何はともあれ、ロジックが複雑になればなるほど、関数型の恩恵は大きくなるわな。
といったって、googleも複雑なシステムとか言われてるけど、
googleを支える技術とか読んでもそんなに複雑とは思えないんだよなぁ。
台数は1台だけど自宅で似たようなことやってるもん。
>>641 P のような再帰的な型のモナドを、
効率のために継続モナド(ReadP)で包むのは定石。
Haskell への慣れっていうより、
モナドや継続モナドへの慣れの問題な気がする。
P は問題によって様々だけど、
ReadP のとこは Control.Monad.Cont の
一般的な継続モナドと(型を除いて)同じなので、
それを理解しておくと問題に集中できていいかもよ。
つ チラシの裏
>>642 それはバックエンドで動いている他プロセスが複雑なのであって
ウェブアプリが複雑なわけではないのでは?
>>644 どうもレスありがとうございました。
>P のような再帰的な型のモナドを、
>効率のために継続モナド(ReadP)で包むのは定石。
これは初めて聞きました。どうもありがとうございます。
確かに
If we want to build monads on top of a continuation based programming paradigm,
such as stream processors or continuation based I/O in Haskell,
we need to build a monad around the continuation based operations.
って書いてあるペーパーを見付けました、その継続ベースの方法について考えながら考えていこうと思います。
>>649 そうです、でもこれだけ読んでもこれで何がしたいのか俺には正直よく分かりませんな。。
例がなくても理論だけ聞けば全て分かるタイプの人なら大丈夫なのかもしれませんが。
>>648 P みたいなのを継続ベースともいうけど、
ReadP を使うのは純粋に効率のためで、
そこに書いてあるのとは話が違うような。
> 純粋に効率のためで
そう単純化されても…
いや、単純だし…
具体的にどういう場合にどうして効率が良くなるんですか?
ReadPだと、PがReadPで包まれてるわけだけど、
get' = Get return
look' = Look return
sat' p = do a <- get' ; if p a then return a else Fail
char' c = sat' (c == )
string' s = do str <- look' ; scan s str
where scan [] _ = return s
scan (x:xs) (y:ys) | x == y = do get' ; scan xs ys
scan _ _ = Fail
みたいにReadPでくるまないバージョンも用意できて、それもrunで使える。
http://www.cs.chalmers.se/Cs/Grundutb/Kurser/afp/2006/Papers/parser-claessen.pdf ここにも効率がって書いてあるけどどんな場合なのかさっぱりだ。。
>>655 どうもありがとうございます。
実際にはReadPの所はR Get やR Lookなどが渡されることになりますよね。
そのあとすぐにrunで即Rはずしてますし。
>Pは直接的にはうまく束ねることができないから
これってどういう意味で仰ったんですか?
P を束ねてパーサとして使うことも、実際できる(
>>654のget'など)のでわざわざどうしてReadPにするのか、
Pの>>=が左結合的に作用するのが問題らしいんですけどそれが問題になる具体的なケースについて
私にはサッパリ思い付かなかったので先人たる皆様にお聞きしたかった次第です。
>>654 ReadP の計算で左結合になってる >>= がある場合でも、
内側の P の >>= をすべて右結合にすることで、
P の >>= の再帰が無くなって効率が良くなる。
9節の第1パラグラフに書いてある通りなんだけど。
左結合を右結合にってのは、>>= の結合則
(m >>= f) >>= g == m >>= (\a -> f a >>= g)
の左辺を右辺にするってな話。
例えば、string s >>= f でも string s の中で
>>= を使ってるので、左結合になってる。
つまりほとんど全ての場合に当てはまる。
効率が悪くなる事情は、そこにも書いてあるようにリストの ++ と同じ。
リストの ++ は左引数に関して再帰する。
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
そのため (xs ++ ys) ++ zs は xs に関して二重に再帰することになる。
foldr (++) [] (map show [1..10000])
foldl (++) [] (map show [1..10000])
実際これらを実行してみると前者はすぐ終わるけど、後者は "1" を10000回結合、
"2" を9999回結合、... "10000" を1回結合、みたいになって遅い。加速してくけど。
遅いだけじゃなく、中間リストを生成するので無駄にメモリを使うことにもなる。
foldl は極端な例だけど、foldr も極端で、いつも無駄が無いようにはいかない。
で、回避策。
xs ++ ys は、xs の最後の [] を ys に置き換える。
それを効率よくやるには、最初っから [] なんか使わないで、
1:2:3:[] を \nil -> 1:2:3:nil みたいにしとけばいいじゃんという発想。
つまり [a] を [a] -> [a] に、xs を xs ++ に、++ を (.) にする。
こうしておくと、[] を与えてリストに戻すときには、
(.) が右結合になってなくても ++ は右結合になる。
(((xs ++) . (ys ++)) . (zs ++)) []
= ((xs ++) . (ys ++)) (zs ++ [])
= (xs ++) (ys ++ (zs ++ []))
= xs ++ (ys ++ (zs ++ []))
実際 String の ++ を頻繁に使う class Show あたりでは、
できるだけ type ShowS = String -> String を使うことになってる。
shows :: Show a => a -> ShowS を使ってさっきの
foldl (.) id (map shows [1..10000]) []
をやってみると、今度は問題無く速い。
で、ReadP。
m >>= f (P の >>=)は、m の最後の return a を f a に置き換える。
それを効率よくやるには、最初っから return なんか使わないで、
Get (\c1 -> Get (\c2 -> return [c1,c2])) を
\k -> Get (\c1 -> Get (\c2 -> k [c1,c2])) みたいにしとけばいいじゃんという発想。
つまり P a を forall b. (a -> P b) -> P b に、
m を m >>= に、>>= を \m f k -> m (\a -> f a k) にする。
以下略。
で、余談。
foldr c n xs は、xs の : を c に、[] を n に置き換える。
それを効率よくやるには、最初っから : や [] なんか使わないで、
1:2:3:[] を \c n -> 1 `c` 2 `c` 3 `c` n みたいにしとけばいいじゃんという発想。
つまり [a] を forall b. (a -> b -> b) -> b -> b にする。
リストに戻すときは build xs = xs (:) [] を使う。
すると foldr c n (build xs) ==> xs c n と変換できる。
map f xs <==> build (\c n -> foldr (c . f) n xs)
例えばこういう変換を定義すれば、
(map f . map g) xs = map f (map g xs)
==> build (\c n -> foldr (c . f) n (build (\c n -> foldr (c . g) n xs)))
==> build (\c n -> (\c n -> foldr (c . g) n xs) (c . f) n)
==> build (\c n -> foldr (c . f . g) n xs)
==> map (f . g) xs
のように map f . map g ==> map (f . g) という変換ができる。
map f . map g 以外にも、他のいろいろなリスト関数の
foldr/build を使った形への変換を定義しておけば、いろいろな変換ができる。
foldr/build による融合変換ってやつ。今の GHC もこれを使ってる。
詳しくは GHC User's Guide の 8.13. Rewrite rules あたりを見てくれ。
>>657-661 とても分かりやすい解説どうもありがとうございます!
ちょっと解決の糸口がつかめた感じがします、これからじっくり考えてみたいと思います。
とてもご丁寧にありがとうございました。
流石だ。。。
Haskellが宣言型言語とか最初に言い出したのは誰なのかしら
imperative language ←→ declarative language の対比で
ごく自然発生的なものだと思うが?
宣言型言語 = what(何をしたいか)を記述
手続き型言語 = how(どうやるか)を記述
クロージャをいかに早めに潰すかに苦心するHaskellは後者ですな
>>665 宣言型言語=述語論理を記述
と思ったらHaskellも述語論理の仕様記述言語に非常に近い特徴を持っていることに気づく。
>>665 > クロージャをいかに早めに潰すかに苦心
ってどういうこと?
>>667 関数のインライン展開のようなものじゃないか
よく分からんが
関数リテラルなら展開しやすいが高階関数の戻り値のクロージャは展開しにくい気がする
だからどう書くか (how) を工夫する
人間が問題を「宣言」するだけでコンパイラが問題を解いてくれる
というのは
素朴な解決策は簡単に見つかるのだが最適化が難しい (が機械的にできる) 問題に限定されるはず
計算資源が有限なため、howが分からないとwhatも記述できないという罠
本質的には what -> how の書き換えと how -> how の最適化は似たようなもんだからな。
最適化は手続き型でもやってるから、非手続き型の人はwhatの部分を強調してみたりC/C++より速くなると言ってみたり。
LLの人は最適化にあまり拘らないし、テストさえ通ればhowを直接書いてもいいやって感じだけど。
>>667 >>600前後の流れ参照
要するに未評価の式(これはクロージャで実装されてる)を溜め込まないように注意する必要がある
しかし、そんなこと言ってたらprologだって宣言型と言えなくなるんじゃない?
お前らは
人間の性格はA型B型O型AB型の4種類に分けることができる
とか思ってそうだよな。
なんでも過不足なく分類できると思い込む愚かさ
血液型と性格をろくな検証なしに簡単に結びつけてしまう短絡さ
どっちをさしてるのか紛らわしいので例としては不適
676 :
デフォルトの名無しさん:2008/09/01(月) 07:57:32
zipで(ry
>>666 プ
試しにZあたりの実行系でもつくってみればw
>>678 何が言いたいのははっきり言え。
小馬鹿にするだけでは情報価値ゼロだぞ。
述語論理なめんな、ってことじゃね?
せめてホーン論理に限定するとかじゃないと話にならんだろ。
681 :
デフォルトの名無しさん:2008/09/03(水) 23:53:10
関数とKleisli以外のメジャーなArrowってあるの?っていうかArrowって死滅したの?
>>676 おお!でも英語疲れる。訳書出版の予定はないの?
>>681 死滅しそうなのはHaskellだが、新しいHaskellのライブラリはほとんどArrowベースだよ。
このスレって嘘多いよな。
このスレって〜
ってレス多いよな。
そういえば、大学入試のときに大学ランクとタバコの関係に気づかされたなぁ・・・
東大 誰も吸っていない
京大 誰も吸っていない
同志社大 ちらほら
関西大 校舎内で吸っているやつがいる(!!!)
ありえないです、低ランク大・・・
やっぱりランクの低い大学出身のやつは信用できない・・・
そして増える意味不明なレス
>>684 素人なのでどの変がうそなのか教えてください
686みたいな奴がhaskellを使うとはとても思えんのだが、
何しに来てるのかね?
>>689 Haskellがどういうものだと思っているんですか?
>>686は今マルチされてるコピペ、スルー推奨です。
>>690 全角数字を見るといらっとくる人が使う言語
確かにイラっときた
>>693
それはカルシウム不足
695 :
デフォルトの名無しさん:2008/09/06(土) 23:15:53
Haskellで良いコード綺麗なコードというのはどんなコードですかね。
出来るだけ変数使わない方がいいとか、何が何でもポイントフリーにするとか、
あるいはそれ以外でも、何でも。
>>695 haskellでは数学的にきれいなコードが「きれいなコード」と呼ばれます。
良いコード:
意味のあるところでControl.*を使う
悪いコード:
ポイントフリーのためにControl.ApplicativeやControl.Arrowをimport
699 :
デフォルトの名無しさん:2008/09/07(日) 00:15:18
っていうか、ポイントフリーってなにがいいの?せっかくパターンマッチがあるのに。
>>687 ライブラリはそうだろうけど、普通のアプリを書くときは?
単純な場合には無駄に変数が増えず、シンプルに分かりやすくなるから良い。
複雑な場合には無理をしても分かりにくくなるだけだから悪い。
パターンマッチとは使いどころが違う。
>>699 圧倒的に短く書けるからだよ。
それにポイントフリーだと関数の入出力の流れみたいなのがまっすぐ表せるから、処理の全貌が見通しやすい
まっすぐだけど、流れが逆じゃん。
というわけで>>>使うのはやっぱダメ?逆なのに脳味噌合わせるべきなの?
GUIアプリを書くときはどういうのが綺麗なんだ?
>>702 逆なの? y = f x より x f = y が脳味噌に合ってるの?
>>704 なんでやねん。
unlines . take 10 . filter (> 10) . map read . lines
より、
lines >>> map read >>> filter (> 10) >>> take 10 >>> unlines
の方が、少なくとも俺は脳に優しく感じる。
で、こう書くと、map read と filter (> 10) を分けてるのが冗長でダサい気もするが、
(filter (> 10).read)みたいにした方が良いのか、かえってこっちの方がダサいのか、
あるいは、(filter (\x -> 10 > read x)) みたいにラムダにすべきなのか、綺麗の勘所が判らんのです。
>>705 あ、前半がStringに戻してないのはご愛敬と言う事で、よろしく。
>>705 String に戻さないといけないなら
filter ((10 <) . read) だろう。ラムダでもいいけど。
まあ、その辺はこだわるとこでもないかと。
> なんでやねん。
f (g x) と (f . g) x の向きは関係あるんですよ。
数学でも向き的事情から x^f という記法を使うこともある。
>>702 左から右だろうが右から左だろうがどっちでも一緒だろ。
俺には違いが分からん。
>>702 こういう反抗したい年頃のやつが言語を汚くしていくんだろうな。
なんでもないものを指差して「使いにくい」などと言ったり、まるでガキ。
現代日本では横書き文字は左から右だから、
その方が自然に感じるのは当然と思います。
また、bind演算子が(>>=)で左結合である事を考えても
Haskellを設計した人もその方が自然と感じたのではないでしょうか?
慣れの問題かもしれませんが、
そんなにおかしな意見とは思えません。
まあ関数合成の向きが右から左なのは
>>707の説明の通りだし、Haskellに限らず数学でも同じルールだからな。数学でも気持ち悪いって云う人は結構居るしまあそんなに変わった意見でもあるまい。
社内コーディング規約でここにスペースを入れろとかそういうのよりは高尚が感じがするかもしれないけれど
所詮バイクシェッド
乱用すれば読みにくいし、パズルみたいにポイントフリーするのは間違ってる
数学的に綺麗綺麗とか、圏論的に自然とかというけれど、誰でも圏論がわかるわけじゃないし。
しかし、いかにポイントフリーで書くか、という事を考えると確かにおもろいよ
s/HDL/VHDL/
Real World Haskell
November 15, 2008
待ち遠しい。
>>717 そうだろうね。
俺はずううっと前からそう論文に書いてたけど。
だんだんpi-calculusの人気が出てきたね。
> Sweeney氏は純粋関数型言語のもつ並列処理安全性に着目しており、
>将来的にゲームプログラミングはそういった処理系に移行していくべきだとした。
>Sweeney氏はそのひな形として言語“Haskel”を挙げているが、
>ゲーム開発のメインストリームたり得る言語はまだ登場しておらず、将来に期待しているという。
なんでHaskellは駄目なんだろう。
ライブラリ含めた開発環境の問題か処理系の最適化の問題か
それとも言語仕様レベルで本質的に向いていないのか。
720 :
デフォルトの名無しさん:2008/09/13(土) 00:06:19
前者じゃない?
こんなことでもないと注目せんのだな
遅延評価に漬かりまくりで、ダメなのでは?
遅延評価って言ってみれば、後ろからの逐次でそ?
無限リスト使えないHaskellってHaskell?
LazyがいやならSMLやOCAML使えばいいだけ。何が不足よ?
質問です
たとえばJavaなどではクラスのインスタンスをオブジェクトと呼びますが、
Haskellの代数的データ型に格納されたデータのことをなんと呼べば良いですか?
>>727 「オブジェクト」に対応する用語は普通は「値」でいいんじゃないか
>Haskellの代数的データ型に格納されたデータ
これどういう意味?
型が代数的データ型であるような値のことならそのまま「代数的データ型の値」
代数的データ型の構築子に渡した値のことなら「フィールドの値」くらいか?
data Point = Pt Int Int
x = Pt 0 3
-- xはPoint型の値
-- xのフィールドの値は0と3
Haskellのプログラミングスタイルのことはなんて呼べばいいですか?
ストリーム指向?
関数指向
Haskell系のShellでオススメってある?
>>732 シェルって何のこと?
言語とは関係ないと思うけど。
シェルスクリプトのことを言っているの?
>>733 HSHみたいなやつ
探してみた奴だとどれも開発止まってて…
Haskell風構文のシェルっていくつかあるんだな、ググって初めて知ったわ
Haskell系の自然言語でオススメってある?
lojbanとか?
自然言語じゃないけど
Yiとか使ってる人いるの?
Yi って 彝 ?
740 :
デフォルトの名無しさん:2008/09/17(水) 18:20:56
ぅぃ?
ひょんなことからerlangを勉強し始めたが、構文はともかく、思想としては面白いな。
並行指向プログラミングというのかな?
このパラダイムはオブジェクト指向よりも現実志向のパラダイムのように思う。
Haskellでも並列化がうまくいけばerlangみたいな仕組みを実装できるかもしれない。
# erlangの構文は糞 糞 糞 糞杉
ぅぃゅ
744 :
デフォルトの名無しさん:2008/09/19(金) 20:28:25
コンカレントハスケル?
745 :
デフォルトの名無しさん:2008/09/19(金) 20:34:40
ああ、コンカレントは並行だったか・・・
>>743 私はProlog屋なので、erlangの構文のクソ部分に敏感でない。
お手数かけて恐縮だが、糞の部分を列挙していただけると有難いのだが。
>>742 たぶん、その思想というのはpi-calculusのことかな。
ここのみんなからするとgtk2hsって綺麗なの?
Erlangってpi-calculusベースなのか
>>746 743ではないけど、
receive...endとか、カリー化できないとかではないですか?
>>723 元記事ではSTMが挙げられてるけど、OCamlだと無くね?
>>749 綺麗って何が?Gtk2Hsを使ったコード?
それならあまり綺麗じゃないんじゃない。
GUIを綺麗に書くためのハイレベルなライブラリは
いろいろあるけど、どれも決定打にはなってないような。
gtk2hsと言えば、
gtk_rc_parse_string相当の関数や、
gtk_widget_modify_cursor(これは新しいからか)相当の関数が見付からなくて諦めたことがあります。。
いや私の検索能力が低いだけだと思うんですが、かなり頑張ってもどうしても見つかりませんでした。。。
皆さんgtkやpango、gdkの関数を捜すときってやっぱり根性ですか?
大抵はキャメルケースにすれば大丈夫ですがそうでない時はかなり困りますよねー。。
いや、検索能力の問題じゃなくて、実際に無いんじゃない?
Gtk2Hsのソースgrepしてみて無かったら無いような。
webで読んでるけどreal world haskell凄いヴォリュームだな
一週間やってもまだ終わらん
製本版はもう鈍器レベルだな
なにか面白いこと書いてあった?
url知らないって意味じゃなくて、自分では読む気が無いってことだよ。
ぱっと見た感じでは、名前の通り実際にHaskellで開発する時に「背中に手が届く」本になってる感じ。
たとえばデータベースと通信する方法とか、
GUIを作るときのライブラリとかツールとかの紹介とか、
どちらかというと「Haskell逆引きクイックリファレンス」
みたいな感じだね。
目新しいことは何もないけど、逆引きリファレンスとしてはいろんなライブラリとか紹介されていて便利かな。
いろいろサンプルコードも載ってるからわかりやすい。
文章の良よりコードの両方の方が多いから英語が苦手な人でもわかると思う。
良 → 量
コードの両方 → コードの量
Parsec.Tokenをロードすると
ERROR file:{Hugs}\packages\parsec\Text\ParserCombinators\Parsec\Token.hs:64 - Syntax error in data type declaration (unexpected `.')
とでて読み込めないのですがどうしたらいいのでしょうか
>>763 Hugsを標準モードじゃなくて拡張モードで起動すればいい
hugs -98
>>764 無事読み込めました。ありがとうございます
766 :
デフォルトの名無しさん:2008/09/24(水) 15:23:46
do構文で、変数の使用が強制されるのはなんとかならんの?
.とか$とかの気の利いたバージョンない?
何を言ってるのかよく分からんが >>= とか?
>>=だけですっきりいけるならdo構文使わないでしょ(ってこともないか?少なくとも俺は)。
do構文でモナドを「外す」ためだけに一時変数がやたら必要になるのがイヤって話。
つまるところ>>=になっちまいそうな気もするけど、
便利な演算子なり特殊なカッコなりで、無駄な変数使わずに何とかならんかなぁ、と。
なにか具体例見せてくれ
do式の中で、
a <- v
b <- f a
は、aを使わずに
b <- v >>= f
と書ける
同様に、
a <- v
let b = f a
は、
b <- liftM f v
と書ける
こういう話?
>>=は普通にdo構文の内部で使えるよ
俺はこの場合=<<を使う方が好きだけど
何を言ってるのか俺もよく分からん。
do ...; a <- m; f a; ...
を
do ...; f =<< m; ... -- m >>= f でも同じだけど...
とか
do ...; a <- m; let b = f a; ...; g b; ...; h b; ...
を
do ...; b <- liftM f m; ...; g b; ...; h b; ...
とかすればいいって話じゃなくて?
って書き込もうとしたんだけどその前に新着レス見たら
>>770被りすぎ。
n <- m
a <- n
を
a <- join m
にするパターンもあるかも。
n <- m
o <- n
a <- o
を
a <- join (join m)
とか。
ぱっといい例は書けないけど、例えば単純な例で
do args <- getArgs
cnt <- getContents
now <- getClockTime
return someFunc args cnt now
を、
do return soumeFunc #getArgs #getContents #getClockTime
とかこんな感じに書けないかと。(#が架空のモナド外し演算子とか)
>>770,771,772
ありがとう。特にjoinは使った事なかった。
俺がアホでした。
あれ?やっぱ違うや。求めてるのとjoin。いや、それはそれで勉強になったけど。
というか、liftM3ですね。とりあえず釣って来ます。
ちなみに、
do args <- getArgs
cnt <- getContents
return otherFunc args True cnt
だったら?
>>773みたいな構文は俺も欲しい
このスレで前に同じことを書いた記憶がある
Template Haskellを使えばなんとかなるかな
>>777 liftM3 otherFunc getArgs (return True) getContents
不恰好だけど
>>773 は Control.Applicative を使って
soumeFunc <$> getArgs <*> getContents <*> getClockTime
や
return sumFunc <*> getArgs <*> getContents <*> getClockTime
って書ける。infixl 4 # ; (#)=(<*>) とすればあのままいける。
っていうのは
(return soumeFunc) #getArgs #getContents #getClockTime
じゃなくて
return (soumeFunc #getArgs #getContents #getClockTime)
のつもりだろうから嘘だけど。
ただ、IO は Applicative のインスタンスになってるけど、
一般のモナドは WrappedMonad って型が用意されてるだけなので、ちょっと面倒。
でも Control.Monad に <*> と同じ意味の ap ってのがあってこれはどのモナドにも使える。
<$> とかの Control.Applicative にあるいろいろな関数がないけど。
あと Control.Applicative には f (a -> b) -> a -> f b な関数が無いけど
それを f *$ x = f <*> pure x とか定義すれば
liftM3 otherFunc getArgs (return True) getContents は
otherFunc <$> getArgs *$ True <*> getContents と書ける。さすがにキモイ。
おおっ、あるのね。
俺の見る程度の範囲じゃ<*>とかはあんま見ないけど、そういえばapは見るな。
まあ、
>>698とか見ると、
>>778の書き方が普通は落とし所って所かも知れんけど、調べてみます。
windows環境でunix 2.3.0.0のインストールに成功した方っていらっしゃいますか?
私の環境では以下のエラーを吐いてbuildに失敗します。
compiling dist\build\System\Posix\DynamicLinker\Module_hsc_make.c failed
command was: C:\ghc\ghc-6.8.3\bin\ghc.exe -c -package base-3.0.2.0 -package directory-1.0.0.1 -Iinclude dist\b
uild\System\Posix\DynamicLinker\Module_hsc_make.c -o dist\build\System\Posix\DynamicLinker\Module_hsc_make.o
どなたか知恵をお貸しください
--unix.cabal
>The package is not supported under Windows (except under Cygwin).
Windowsは基本的に非サポート、
Cygwin環境下はOKという意味だと思ったんですが違いますか?
長くて貼れなかった部分(すみません)のログを見てみると
cygwinのフォルダにあるheaderファイルの発見に失敗しているようでした。
終電の時間が近いので、検索パスの追加をした所で今日は帰ります
783 :
デフォルトの名無しさん:2008/09/25(木) 00:01:22
仕事でハスケル使ってんの?
言語設計学者の悲願の言語だけど、開発環境はまだ全然整備されていないから、ほぼ0
学生だろ?
786 :
デフォルトの名無しさん:2008/09/25(木) 03:18:09
学生のうちから終電まで勉強してんのかよ。
そんなんじゃ社会に出てからもたんぞ。
Schemeのcondみたいのはどう書くのがよいでしょうか?
case でマッチング無しガードのみにすればとりあえず出来るけど、dummyや_が冗長。
case dummy of
_ | conditionA -> bar
| conditionB -> foo
otherwise -> baz
そこだけ別函数にしちゃえば良いんじゃ?
こういうsyntax sugarが欲しいなあ。
data X = A | B | C | D
case x of
A | B -> 1
C | D -> 2
確かに欲しい
でも縦線だとガードに見えるから別の記号が要るな
792 :
781:2008/09/25(木) 20:53:49
だめでした。
定義されていない型、定義されていない関数のエラーは
HsUnix.hに手を加えてなんとかしましたが(includeするファイルを追記)
↓結果
dist/build/System/Posix/DynamicLinker/Module_hsc_make.o(.text+0x49):Module_hsc_make.c: undefined reference to
`_impure_ptr'
dist/build/System/Posix/DynamicLinker/Module_hsc_make.o(.text+0x8d):Module_hsc_make.c: undefined reference to
`_impure_ptr'
dist/build/System/Posix/DynamicLinker/Module_hsc_make.o(.text+0xb5):Module_hsc_make.c: undefined reference to
`_impure_ptr'
dist/build/System/Posix/DynamicLinker/Module_hsc_make.o(.text+0xe9):Module_hsc_make.c: undefined reference to
`_impure_ptr'
collect2: ld returned 1 exit status
linking dist\build\System\Posix\DynamicLinker\Module_hsc_make.o failed
それはともかく、今夜はwww.haskell.orgに繋がりにくいですね
>>790 そういう、かゆいところに手が届くのは、やっぱりLISP系最強なんだろうか。
流行に乗ってHaskellを勉強しているのですが、バイナリファイルの扱い方に困ってます。
int numFloat;
int numInt;
float floats[numFloat];
int ints[numInt];
C的な擬似コードで書くとこんな感じのバイナリファイルに対して、
floatsとintsのデータを取ってきて文字列でフォーマット化して表示してみよう、と思っています。
hFile <- openFile filepath ReadMode
cs <- hGetContents hFile
ひとまずこれで[Char]を持ってきて、そこからnumFloatとnumIntを切り出せばよいか、
と思ってるのですが、じゃあそれってどうするんだろう、ってところで詰まってます。
(numFloat,numInt,残り) = hogeFunction cs
みたいな感じで切り出すのが関数型的な感じなのかな、と思っているのですが、
そもそもこの辺の考え方からして駄目っぽいですか?
>>795 ありがとうございます。
BinaryModeって付けないと駄目なのと、
あとPtrを経由してデータを取ってくるんですね。
これで勝つる!
べつにPtrを経由しなくても
>>794の方針でいけるよ
効率を気にするなら別だけど
>>797 テキストモードの場合、、
control-ZをEOFと認識したり、CRLFを LFに変換すると
GHCのマニュアルにありますが、
問題ないのでしょうか?
>>799 問題ある
>>797は、バイナリモードで開いた上でgetContentsすればいい、という意味で言った
>>798 確かにそうだな
ちゃんとテストしてないけど一応こんなんでいけるみたいだ
import Data.Bits
import Data.Word
w32ToFloat :: Word32 -> Float
w32ToFloat w
| ep == 255 && sf /= 0 = 0 / 0
| sf == 255 = sign / 0
| sf == 0 && ep == 0 = sign * 0
| otherwise = sign * encodeFloat r e
where
sn = shiftR w 31
ep = shiftR w 23 .&. 0xff
sf = w .&. 0x7fffff
sign = if sn == 1 then -1 else 1
e = fromIntegral ep - 127 - 23
r = fromIntegral sf + 0x800000
バイト列をFloatとして解釈させたいわけだから、
必要なのは Word32 -> Float じゃなくて [Word8] -> Float なんじゃなかろうか。
というわけでPtr経由だけど書いてみた。
import Foreign
fromBytes :: Storable a => [Word8] -> a
fromBytes bs = unsafePerformIO $ allocaArray (length bs) $ \ p -> pokeArray p bs >> peek (castPtr p)
toBytes :: Storable a => a -> [Word8]
toBytes x = unsafePerformIO $ alloca $ \ p -> poke p x >> peekArray (sizeOf x) (castPtr p)
toBytes (0.5 :: Float) => [0,0,0,63]
fromBytes [0,0,0,63] :: Float => 0.5
で、整数のendianはどうするとか色々とケチがついていくにしたがって、重くて遅いコードに変身していくわけだ。
endian変更は[Word8]にreverseかければ良いんじゃね。
システムのendian判定はこんな感じ?
isLittleEndian = (1 :: Int) == fromBytes [1,0,0,0]
isBigEndian = (1 :: Int) == fromBytes [0,0,0,1]
やっぱり
>>800にはバグがあった
- | sf == 255 = sign / 0
+ | ep == 255 = sign / 0
>>802 [Word8]からWord32を作って、そこからFloatにすればシステムのendiannessを気にする必要ないよ
この場合PtrやUArrayを経由するのでもencodeFloatでも良い
-- テストしてみた。
-- import Test.QuickCheck
(f `eq` g) x = Result (Just (f x == g x)) [] [show (f x), show (g x)]
forAllBinaryFloat :: (Testable b) => ([Word8] -> b) -> Property
forAllBinaryFloat t =
forAll (choose (0,1)) $ \s ->
forAll (oneof [elements [0,255], choose (1,254)]) $ \e ->
forAll (oneof [elements [0], choose (1,2^23-1)]) $ \f ->
t (sefToBytes s e f)
sefToBytes :: Int -> Int -> Int -> [Word8]
sefToBytes s e f = endian [shiftL s' 7 .|. shiftR e' 1, shiftL e' 7 .|. f1, f2, f3]
where
[_,f1,f2,f3] = endian (toBytes f)
[s',e'] = map fromIntegral [s,e]
endian = if head (toBytes (1 :: Word32)) == 1 then reverse else id
prop_float :: (Float -> Float) -> Property
prop_float fl2fl = forAll (oneof fls) (id `eq` fl2fl)
where fls = [elements [0,{-0/0,-}1/0,-1/0], fmap (/ 2^127) arbitrary, arbitrary]
prop_bytes :: ([Word8] -> [Word8]) -> Property
prop_bytes bs2bs = forAllBinaryFloat (id `eq` bs2bs)
-- quickCheck test1 や verboseCheck test5 とかで実行。
test1 = prop_float (fromBytes . toBytes)
test2 = prop_float (w32ToFloat . fromBytes . toBytes)
test3 = prop_float (uncurry encodeFloat . decodeFloat)
test4 = prop_bytes (\bs -> toBytes (fromBytes bs :: Float))
test5 = prop_bytes (toBytes . w32ToFloat . fromBytes)
test6 = forAllBinaryFloat $ \bs -> not (isNaN (fromBytes bs :: Float)) ==>
(fromBytes `eq` (w32ToFloat . fromBytes)) bs
{- 1, 3 は通った。最初 NaN/=NaN をうっかりした。
w32ToFloat は非正規化数を無視してるので、2, 5, 6 が通らなかった。
4 は NaN のときに、仮数部の最上位ビットがおかしくなった。
5 は w32ToFloat は NaN を全て 0/0 にするのもあって通らなかった。
NaN の表現が変わるのは Float を解釈する場面
(つまりコピーとかじゃない)なら問題無いだろうけど。-}
QuickCheckすげー
盲目的なランダムテストだけじゃないのな
概念的には、(ieee754で表現される)外部フォーマットのデータを読んで、
ネイティブのFloatに変換して使いたいのか、
それともieee754データとしてそのまま扱いたいのかでやることが変わってくるな
実際にはどうせieee754を採用してるアーキテクチャでしか動かさないから、ショートカットが効くわけだけど
QuickCheckってどうも使い方が解らない。
テストが元実装と結局ほとんど同じにならない?
元実装は仕様をすでに表してるわけで、その仕様にあってるか確認するコードは、
結局同じになるのは必然だと思うんだけど。
仕様から演繹出来る他の事を確認しろって事かな?
でも、演繹で導かれる事が、元仕様とは別の理由で成り立つ事もあるよね?
>テストが元実装と結局ほとんど同じにならない?
ならない。
>>805-806を見れば分かる通り
>元実装は仕様をすでに表してるわけで、その仕様にあってるか確認するコードは、
>結局同じになるのは必然だと思うんだけど。
そういう場合もあるし、そうでない場合もあるから、決して必然じゃない
たとえば、ソート関数が正しいかどうか確認するコードと、
実際にマージソートやクイックソートをするコードは全然違うものになる
さらに「マージソートでもクイックソートでも結果が同じになる」みたいなのもテストになるし
>でも、演繹で導かれる事が、元仕様とは別の理由で成り立つ事もあるよね?
もちろん
だれもテストで全ての誤りを発見できるとは思ってない
あと、ランダムテストが有効な場合とそうでない場合があるよね。
>>805-806はあまりランダムである必要が無いかも。
きわどいケース(上の場合だと0、非正規化数、無限大、NaN)を
並べ上げにくい場合にランダムテストが有効な気がする。
ああそうか、例えばソートの例の場合、
「正しくマージソート出来てるか」じゃなくて
「正しくソート出来てるか」のテストになるからか。
前者はQuickCheckに関わらず外部テストでは確かめようがないから、
「ソートする」じゃなくて「マージソートする」という仕様はソースレビューするしかないのか。
単なる関数じゃあまり意味がなくて、
結果としてのアウトプットが特徴的で綺麗な性質を持ち、
かつ、その性質自体が目的である場合に威力を発揮するって感じか。
その類の物は、性能が競われる事が多い気がするから、その辺りのサポートもあると良いかも。
2chって連続した半角スペースが に置換されるようになったの?
f :: A -> B のテストは
・B (or A) の == を使う場合
・一般の場合
・h :: A -> B を用意して f x == h x をテスト
・逆関数 g :: B -> A がある場合
・x == g (f x) をテスト
・y == f (g y) をテスト
・使わない場合
・r :: A -> B -> Bool をうまく用意して r x (f x) をテスト
(テストはランダムな x :: A, y :: B に対して)
大概こんな感じ。
元実装とほとんど同じテストってのは、
g やうまい r が無くて、f x == h x というテストしか無いんだけど、
f と違う h も無くて、でも f x == f x じゃバカ丸出しなので、
== を明示的には使わないで実質的に f x == f x と同じことをやる、
みたいな感じじゃないかな。
うわ俺バカ丸出し。&nbsp;って書きたかった。
datを直接見るようにすればnbspなんて使わなくてもインデントされるよ
滅茶苦茶な事を聞いていそうで済みませんが、
cabal configure と runhaskell Setup.hs configure、
cabal build と runhaskell Setup.hs build、
cabal install と runhaskell Setup.hs install、
って何か違うんでしょうか。
同じだとしたらなんのために両方あるんでしょうか。
オラ本でねーぞコラ
cabal なんてコマンドあるの?
あるとしたら runghc Setup と打つより楽だからじゃ?
>>821 RubyGemsなんて目指されると非常に困る。
ん?どんな風に?
質問です。
Haskellにて、二次元配列を時計回りに90度回転させるには、どうすればいいでしょうか?
今あるコードが
rot90 list = reverse (map (head) list) : rest
where rest = if length (concat taillist) == 0 then []
else rot90 taillist
where taillist = map tail list
ですが、ものすごく非効率的だと思います。
>>824 length (concat taillist) == 0
の部分を
all null taillist
にでもすれば別に非効率的でもない気がする
俺ならtransposeを使うな
rot90 = transpose . reverse
>>825 素早い回答ありがとうございます。
実は、transposeも定義しないといけなく、transposeでrot90を使っているので…。
transpose list = rot90 (hflip list)
hflip list = reverse list
というふうになっております。
どうしてもrot90でtransposeを定義しなきゃいけないの?
そうでなくて単にtransposeが必要ってだけならその定義は捨てて
import Data.Listしてtransposeを使えば良いんじゃない?
transposeって標準の関数ではないんですか?
>>827 課題では、自分でtransposeを定義しろ、とのことでした。
>>828 Prelude関数ではないのでData.Listをインポートしないと使えない。
>>829 だったら
>>825 が最初に言ってる変更をするか、rot90を使わずにtransposeを定義すれば。
Data.Listのtransposeはこれ
transpose :: [[a]] -> [[a]]
transpose [] = []
transpose ([] : xss) = transpose xss
transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) : transpose (xs : [ t | (h:t) <- xss])
>>813 連続した半角スペースはjavascriptモードで書き込むときに置換されるらしい。
>>824-825 長方形じゃないときに、all だとエラー、any だと長方形になるように切り落とす。
filter 使えば
>>831の transpose に map reverse . したような感じになる。
([<h or t> | h:t<-xss] = map <head or tail> (filter (not.null) xss))
違ったやり方なら
rot90 = foldl c []
where
c yss [] = yss
c [] xs = [[x] | x<-xs]
c (ys:yss) (x:xs) = (x:ys) : c yss xs
とか。
あ、any じゃ list == [] のときまずいという話もあるか。
>>823 パッケージの管理方法にいろいろと問題がある。
>>834 具体的に言ってくれよ。そして開発者達にも。
質問です。ディレクトリの階層構造をData.Tree型に納めようとしてい
るのですが、遅延評価が効くようなコードが書けません。
type FileTree = Tree FilePathとして、以下のような関数を作ってみたのですが。
recursiveFileTree :: FilePath -> IO FileTree
recursiveFileTree name = do
contents <- catch (getDirectoryContents name) (\e -> return [])
children <- let
filtered = filter filterDots contents
pathadd = map (\x -> name </> x) filtered
mapped = map recursiveFileTree pathadd
in sequence mapped
return (Node (takeFileName name) children)
where filterDots :: FilePath -> Bool
filterDots "." = False
filterDots ".." =
filterDots _ = True
(インデントしてるように見せるために全角スペースを入れています。見えますか?)
おそらくsequenceで[IO FileTree] -> IO [FileTree]としているあたりが問題なのだと思いますが、解決策が分かりません。
・unsafeInterleaveIOを使う
・Data.Treeを使うのをやめて、明示的なIOを伴う木を定義して使う
好きな方を選んでくれ
一応言っておくが、HaskellのIOは基本的に遅延しないし、普通はそれで正しい
IOは実行順が重要なことが多く、遅延させて順番をうやむやにすると厄介なことになりやすい
それだとどうしても不便というときのためにunsafeInterleaveIOがある
f a b c の部分適用として f a b と書くことはできますが、(\a -> f a b c) にあたる部分適用を a を省略して書く方法はありますか?
flip使え
flip (flip f b) cはさすがに悪趣味だろ
(\a -> f a b c) → 15文字
flip (flip f b) c → 17文字
843 :
デフォルトの名無しさん:2008/10/30(木) 19:39:38
($c).($b).f flip (`f`b) c
f # b c みたいな構文(# は未適用引数を表す)があったら便利だったかもね
SRFI 26 みたいな?
\x->f x b c
>>846 それだと
f # b c -- \a -> f a b cと同等
と
(f #) b c -- (\a -> f a) b cと同等
を区別する必要が出てきて面倒だな
http://d.hatena.ne.jp/m-hiyama/20081031/1225416719 ブログ持ってないのでここで。酒井さんのパクリ。
{-# OPTIONS -fglasgow-exts #-}
import Control.Monad (liftM2)
import Data.Either
import Test.QuickCheck
infix 4 :<->:
type a :<->: b = (a -> b, b -> a)
(.>) :: a:<->:b -> b:<->:c -> a:<->:c
(f1,g1) .> (f2,g2) = (f2 . f1, g1 . g2)
un :: a:<->:b -> b:<->:a
un (f,g) = (g,f)
type a :+: b = Either a b
infixr 5 :+:
alt :: a:+:b :<->: b:+:a
alt = (f,f) where f = either Right Left
swap :: a:+:b:+:c :<->: b:+:a:+:c
swap = (f,f) where f = either (Right . Left) (either Left (Right . Right))
rt :: b :<->: c -> a:+:b :<->: a:+:c
rt (f,g) = (r f, r g) where r = either Left . (Right .)
data T = L | N T T deriving (Eq, Show)
fold :: a:+:(T,(T,a)) :<->: (T,a)
fold = (f,g)
where
f (Left a) = (L,a)
f (Right (t1,(t2,a))) = (N t1 t2,a)
g (L,a) = Left a
g (N t1 t2,a) = Right (t1,(t2,a))
h :: (T,a) :<->: a:+:(T,a):+:(T,(T,(T,a)))
h = un fold .> rt (un fold)
s :: a:+:(T,(T,(T,a))) :<->: (T,a):+:(T,(T,(T,(T,a))))
s = rt (un fold .> alt) .> swap .> rt fold .> alt
st :: (T,a) :<->: (T,(T,(T,(T,(T,(T,(T,a)))))))
st =
-- T
h
-- 1 + T + T^3
.> swap
-- T + 1 + T^3
.> rt (s .> s .> s .> s
-- T + T^4 + T^7
.> alt)
-- T + T^7 + T^4
.> swap
-- T^7 + T + T^4
.> rt (s .> s .> s .> s .> s)
-- T^7 + T^6 + T^9
.> swap
-- T^6 + T^7 + T^9
.> un h
-- T^7
instance Arbitrary T where
arbitrary = oneof [return L, liftM2 N arbitrary arbitrary]
main :: IO ()
main = do
quickCheck $ \x -> x == (snd st (fst st x) :: (T,()))
quickCheck $ \x -> x == fst st (snd st x :: (T,()))
型検査で漏れてるのは fold の定義ぐらいで、QuickCheck 意味ないのかも。
すげえ、読みやすいな
856 :
デフォルトの名無しさん:2008/11/05(水) 07:40:02
GHC 6.10.1リリースあげ
((f.) . g) a b
みたいなテクニックが沢山載ってるようなページを教えてください
unsafeInterleaveIO :: IO a -> IO a
unsafeInterleaveIO (IO m)
= IO ( \ s -> let
r = case m s of (# _, res #) -> res
in
(# s, r #))
この#って何なんですか?ghc6.8.2ではエラーになりますし…
>>859 ありがとうございました
拡張構文なんですね
weakリダクションって何?
googleで検索したらひっかかったので、ここに書かせていただきます。質問していいでしょうか?
Haskellの処理系だけを使って、prologみたいなことができないか調べています。
↓でprologのタプル parent(tom, bob). のような感じにすると、
parent::[Char]->[Char]->Bool
parent "tom" "bob" = True
parent "liz" "bob" = True
parent "mike" "liz" = True
parent _ _ = False
とりあえず、
main = print $ parent "tom" "bob"
main = print $ parent "mike" "bob"
で True や False が出て、prologっぽくなります。
そこで、
parent X "bob"
という質問に対し、
X=tom
X=liz
みたいに変数にユニファイするような定数を手に入れるような仕組みってあるでしょうか?
入門書に、コンパイル時に内部でグラフを作るみたいな話が書いてあったので、
そのグラフを参照できるようなことができれば実現できると思うのですが、無理でしょうか?
>>862 無理
Haskellの関数は文字通り関数なので、引数を放り込んで結果を観察する他に使い道は無い
中間形式のグラフみたいなの見れないのん?
中間形式のグラフって何?
グラフ簡約のことを言ってるのなら、グラフが作られるのは実行時だし、
要するに「未評価の式」を表してるだけだから、それを見ても
>>862みたいなことをする助けにはならんよ
少なくとも書こうとしてるプログラムの中からは見れない。
Haskellって厳格な言語で、その手の変なことは基本的にできないよ。
何をやりたいのか知らないけど、インタプリタ的なものを書いて、
それをライブラリとして使えば?
ん、普通にMaybeとかそれ以前にListモナドとか使えば普通に実現出来るって云うかモナドのすべて読んだ方が良いと思うよ
関数から引数への参照は、関数が展開されても複数の場所から同じ場所を参照するという話と、
先にグラフを作って、実行時に、そこにデータを流し込むような感じの説明があったから、
処理系をそのまま利用して、かなり高速なデータベースが作れると思ったんですけどダメですかね。
実現できればprologよりも表現能力が高いから面白そうだと思ったんですが。
>関数から引数への参照は、関数が展開されても複数の場所から同じ場所を参照する
これはその通り
>先にグラフを作って、実行時に、そこにデータを流し込む
これはぜんぜん違う
多分どこかで誤読してると思う
>>867 zs <- everything
append [1..100] [1..100] zs
こういうやり方じゃ生きてるうちに終わらないかもよ。
Listモナドは、もちろんユニフィケーションや制約伝播なんて無くて、
総当りで解を求めようとする非決定性計算ってだけなんで。
>>872 変数をどう表現して、何をどう枝刈るの?
887 名前:デフォルトの名無しさん[] 投稿日:2008/11/22(土) 00:28:37
Real World Haskellは糞本だと思う
出版されたの?
始まったばかりにしても、ひでえ訳
878 :
デフォルトの名無しさん:2008/11/25(火) 23:41:58
Real World Haskellって翻訳本が出ると思いますか?
マイナーな言語だけど、微妙にブームになってるし
来年ぐらいに出版されたりするかなあ?
確かに一時期あったけど、とっくに沈静化したような…>ブーム
>>879 最近は沈静化したように見せかけて、ジワジワきてるよ。
各大学の卒研レベルではHaskellやったりしてるところが増えてきてる。
881 :
デフォルトの名無しさん:2008/11/26(水) 00:04:13
うーん、訳の出来とは別になんか期待できなさそうな感じ
原文自体平易な英文なので今後のことを考えるなら英文に慣れるために原文で読むことをお勧めします。
まだ10章までしか読めてないけど
ふつケルの次くらいに読む分には悪くないと思う>RWH
タダだし
884 :
デフォルトの名無しさん:2008/11/26(水) 00:17:39
本買おうと思ったけど、WEBで読めるわけだし
翻訳本が出るまでそれですまそうかなw
RWHクソだろ〜
11章からはページを増やすためにネタを書きましたって
レベルのオナねたのオンパレードだぞ
RWHってネットでもう出回ってるんだなw
出回ってるつーかあれを最近本にしたんでしょ?
888 :
デフォルトの名無しさん:2008/11/26(水) 00:49:09
存在型ってなんですか?
バキシルとか大麻のことだ
890 :
デフォルトの名無しさん:2008/11/26(水) 01:48:33
ありがとうございます。
Haskell: The Craft of Functional Programming
と
Programming in Haskell
のどちらがお勧めですか?ふつけるの次くらい。
>>884 下手糞な翻訳の恐れ大。最近多いね、いや昔からか
894 :
デフォルトの名無しさん:2008/11/26(水) 22:52:49
Programming in Haskellはいいよ。ふつけるの前でもいいです。
>>892 自分はふつけるの後にCraftでした。というか、その間にSICPが
あるので、あんまり参考にならないかな。ふつける読んでも
ちょっとピンとこなかったんですね、よくまとまってるとは思うのですが。
自分は普通の文系プログラマで、関数型プログラミングの世界とは
無縁だったので、SICPをくぐる必要があったと感じてます。
896 :
デフォルトの名無しさん:2008/11/27(木) 19:30:50
Craftはいつ第3判が出るのですか?
Craft第2版以降で目立ったHaskellの技法というと、Arrowぐらいでしょうか。
あとはReal Worldみたいな実用面を書いたものになりますかね。
ガンズのニューアルバムが出るころに出版されるそうです。
それは出版されないってのとどう違うのだ
泳げる頃にh(ry
1版ならともかく3版なら別に出なくてもいいんじゃね
Implementing Functional Languages: a tutorial
ってのをやってますが、練習問題の回答とかどっかに転がってますでしょうか。
>>902 著者本人が公開してる。あとは自分で探せクズ。
自演乙
Haskellで書かれた数式処理ソフトがあると聞いたのですが
maximaと比べると
言語から直接利用するときの利用しやすさは、どんな感じなのでしょうか?
PJの答を探しているクズ、どこのゼミ生かしらんが、これで次の輪講はアウトだなwww
908 :
902:2008/11/30(日) 09:56:28
>>907 自分では探してみましたが、部分的なコードだけしか見つけられませんでした。
ちなみに、自分は学生ではないんです。輪読の場があったりしたら入りたい
ですけど、ちょっと今は時間的に厳しいかな。ネットでやってたりするといいん
ですが。
探すもなにも、入手方法ちゃんと書いてあるじゃんwww
910 :
デフォルトの名無しさん:2008/11/30(日) 21:28:44
>>896 2021年4月19日に出るみたいです。
まだ相当先ですね。
どんどん延期してると思ったら
今度はありえないくらいに延ばしたな・・・
912 :
デフォルトの名無しさん:2008/12/07(日) 12:54:19
ghci の補完って windows じゃ効かないんですかね。
Linux 上だとちゃんと動いて便利だったのでショックです。
ネット探してみると rlwrap 使えとかあったけど
rlwrap って動的な補完(スコープ内の関数一覧等)
って可能なんでしょうか。
そんな高度な補完はemacsのinferior-haskellとかeclipseの拡張でもできるかどうか怪しいな
英語配列30g早く!
915 :
902:2008/12/07(日) 20:05:48
>>909 書いてありました。これって個人でも送ってくれるのでしょうかね。
ただ、まだ半分ぐらいなんですけど、問題簡単なので別に解答不要
になりそうです。ありがとうございました。
do記法と(>>=)の対応についてですが、
do;putStr "a\n";putStr "b\n";putStr "c\n";
≡
putStr "a\n" >>= (\_->putStr "b\n" >>= (\_-> putStr "c\n"))
なんですかね?
右結合的になったり匿名関数に変換されたりと難しいです
>>916 一緒です。
でも
putStr "a\n">>putStr "b\n">>putStr "c\n"
と書いた方がきれいですよ。
あと、括弧なくても良いですよ。
なるほど、そう言えばlambda式ってかなり優先順位が高いんでしたね
ありがとうございました
F#からポロロッカしてきました
fold/undold、flip とかを使った関数合成がすげえ苦手なんですが
このあたりに特化した書籍とかってないでしょうか
モナドとか継続とかはわりとどうでもいいんですが
undoldって何かと思ったけど、unfoldの間違いだよね?
923 :
920:2008/12/14(日) 17:19:51
間違いですw
>>921 ありがとう
Introduction〜とRealWorldHaskellをぽちってみました
下は高杉…
yet another haskell tutorialの4.6で
cfold' f z [] = z
cfold' f z (x:xs) = f x z (\y -> cfold' f y xs)
という継続fの与え方次第でfoldlにもfoldrにもなるものが出てきたんですが
普通のfoldlやfoldrの定義からこれを導きだす手順のようなものがあるなら知りたいです
また「なんでも再帰」流に一つ引数増やして、最後にそれを必ず呼び出すようにして
末尾再帰の形に直していく…ってやり方で書こうとしてますがさっぱりです
面倒だからfactorialで書くと、
fac 0 = 1
fac n = n * fac (n-1) なのか
fac n = fac (n-1) * n なのかってことだから、
fac n = ((n *) . fac) (n-1)あるいは、
fac n = ((* n) . fac) (n-1)
fac n = (((\m ->(m *)) n) . fac) (n-1)あるいは、
fac n = (((\m ->(* m)) n) . fac) (n-1)
fac0 f n = ((f n) . (fac0 f)) (n-1)で
fac0 (\m ->(m *)) nあるいはfac0 (\m ->(* m)) n
\m ->(m *)と\m ->(* m)は、
fac(n-1)を計算した後にすべき計算、つまり継続になっています。
要するにfoldってのは累積を計算しているのだから、
その累積演算を関数に独立させると、foldの性質上、継続的になるのです。
mapだとこうはなりません。
>>926 ところがどっこい、この説明のすぐ後で、
「CPSを使ってmapとfilterを書け」なんて演習問題が出されてるわけですよ。
それを考えると、foldlの定義からcfold'へ持っていってあげたほうが
親切かもしれません。
あっと、「この説明」ってのは
「yet another haskell tutorial の cfold' の説明」のことね。
>>927 cfold'は、元のfold*の引数に渡す演算自体が継続的になるのに対して、
mapでは引数に渡す演算ではなくて、:が継続的になるわけです。
だからYAHTでは微妙に表現を変えています。
map f = foldr (\x -> ((f x) :)) []
ですから当たり前ですけども。
>>929 すまん、「継続的」という言葉の意味がさっぱり分からん。
CPSにしたときに最後に行われる計算、という意味なら、
foldlは「foldl」自体が継続的、
foldrは引数として渡す関数「f」が継続的ということになるので、
fold*で継続的となる関数が同じになるとは思えない。
931 :
デフォルトの名無しさん:2008/12/21(日) 19:58:16
utf8-stringっぽいかな‥‥
>>930 本人ではないが、
fが継続的(serial):
どのxに対してもあるyが存在してf x yという関係が成り立つ。
クリプキの様相論理で出てくる、でも多分、その意味で使っている
わけではないと思うけど。
クリプキナツカシス
・空でない集合W(要素は可能世界)と、W中の二項関係(到達可能性関係)Rの組をフレームと呼び、F=<W,R>と表す
・そこから到達可能な世界が一つもない世界を dead end と呼ぶ
・Rがserialである⇔∀w∃w'(wRw') = そのフレームには dead end が存在しない
とすると
「必然的にAならAは可能である (□A->◇A)」がフレームFで妥当 ⇔ Rがserialである
…学生の頃のノート読み返してみたがわけわかんね('A`)
専門外のうろ覚えながら
ある世界で□Aが成立するとは、そこから到達可能な世界全てでAが成立することで
ある世界で◇Aが成立するとは、そこから到達可能な世界のなかに、Aが成立する世界があること
という認識でいいのかな。
ある世界で、任意の論理式Aについて『□A→◇A』が成り立つなら、『(◇A)∨(◇¬A)』。
つまり、その世界から到達可能な世界のなかに、Aが成立するものかあるか、¬Aが成立するものがある。
結局、『□A→◇A』は「到達可能な世界が少なくとも1つあり、その世界でのAの成否には言及しない。」と言っているんだろう。
で、全ての世界で『□A→◇A』が成立するなら、全ての世界が「次の世界」を持ち、dead endが存在しない、と。
自然言語に直すと余計にややこしく思える
Haskellの話じゃないのに、Haskellスレっぽい。
モナドは様相だしな
stateのsemanticsをtemporal logicでってのはよくある。
規制か?
StringとIO Stringって何が違うの?
むしろHaskell的にどう解釈すればStringとIO Stringの区別がつくの?
IOの結果得られる文字列がIO String。
例えば、ファイル全体を文字列にして返すreadFileは、
readFile :: FilePath -> IO String
base/GHC/IOBase.lhsより
newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
IOの実体は現実世界の状態をとって、IO動作実行後の状態と型aをもつ値の組を返す関数
と読めるけどいまいち釈然としないなー
まともに理解するには圏論や時相論理とかの知識がいるのかな?
いらないよ。
エラーが起きたかどうかとか、
readLineだと、どこまで読んだかとか、
writeFileだと、書き込んだファイルとか、
そんなのがIOの「状態」。
俺は
>>943 に書いてあるとおり、現実世界を状態としてもつ
Stateモナドの一種だけど runState を書かなくてもいい特別
扱いされたものだと理解している。
gtk2hsもwin32パッケージもインスコできねぇ
StringとIO Stringについてはなんとなく分かった
そういうものと認識していればいいのね
で、IO StringからStringってどうやって取り出せるの?
入門書嫁ですねわかりました
パターンマッチで抜き出す。
REPL的な環境で使ってると、何が違うのか気付きにくいよね……
REPLがそもそもIOモナドだもんね。
トップレベルで扱っていると思っているのはStringじゃなくてIO String。
REPLモナドとか作れそうだな
しかしそういうCUIインターフェースを作るフレームワークって既に誰か作ってそうな気もする
つ $(GHC)/compiler/ghci/GhciMonad.hs
>>952 つ $(GHC)/compiler/ghci/InteractiveUI.hs
template haskell使ったらユニットテスト等で
どんな式からexpectedやgotが算出されたかとか、
このテストケースが書かれたのはソースのn行目、m項目であるとかを表示できるんだねぇ
これ使えばHUnitもRspecとかみたいにテスト結果をもっとkwsk表示するようになるんだろうか
と思ったけど今のsyntaxだと$()だらけで汚いことになるからありえんか
HTFというのがまさしくそれ…のようなんだが
使い方が全然わからねぇ…
Q [Dec]を要求するtestsって何!?
話ぶった切ってすまそ
GHC-6.10 + OpenGL + GLUT の環境で
renderPrimitive LineLoop $ mapM_ vertex [Vertex2 (-0.9) (-0.9), Vertex2 0.9 (-0.9), Vertex2 0.9 0.9, Vertex2 (-0.9) 0.9]
↑これをGHCiで入力すると IO () として正常に扱ってくれるんだが
GHCでソース中に書くと
「Ambiguous type variable `a' in the constraints: `VertexComponent a' arising from a use of `vertex'」
「Probable fix: add a type signature that fixes these type variable(s)」
とか怒られるんだが…
どこでどうダウンキャスト(?)すればいいのかわからない
エロいひとご教示おねがいします
↓自己解決しました
renderPrimitive LineLoop $ mapM_ vertex [Vertex2 (-0.9 :: Float) (-0.9), Vertex2 0.9 (-0.9), Vertex2 0.9 0.9, Vertex2 (-0.9) 0.9]
~~~~~~~
しょぼくてごめん^^
とりあえず、HaskellのMLで圏論の話とかやめてもらえねーかな。
正直、みんな引いてると思うんだよね。
新規参入者が減るからHaskellの話と圏論の話は別のMLに分けた方が良いと思うんだ。
962 :
デフォルトの名無しさん:2009/01/09(金) 14:02:50
このスレでそんな事逝っても意味ないだろバカ
直接そのMLで家よバカ
>>962 代わりに言ってよ
俺は他人の反感買いたくないんだ
Meta Language の方の ML かと思ったから意味がわからなかった
本物の初心者はhaskell cafeへ
Haskellと圏論は不可分なものではない。
単にモナドが圏論チックなだけ。
圏論の議論は圏論のメーリングリストでやればいい。
You Ain't Gonna Need Itですか?
マイナー人間同士仲良くやりなさいよ。
そんなことで剣呑するより圏論する方がいいじゃないか。
圏論厨UZEEE
っていうか、圏論って別にマイナーでもないぞ。
数学じゃ普通に使う。
HaskellのMLに来てるやつは数学系のMLについて行けなかった奴らだろうな。
haskellと一緒に勉強すると単品でやるよりわかりやすいらしい
おしりまん
Real World HaskellってAmazonのComputers & Internetカテゴリで
ベスト11に入ってる。配下のProgrammingでは5位。
すごいな。Haskellってこんなに流行ってるのか…
SICP が売れて Scheme が流行ったか?
学生が主に買ってるってこと?
現在8位 どんどんあがってる haskellの時代きた
Amazonの順位は簡単に上下するぞ
まず日本語を理解しろ
なんで自己啓発してんの?