関数型プログラミング言語Haskell Part16
■ このスレッドは過去ログ倉庫に格納されています
0001a36 ◆K0BqlCB3.k
2011/10/07(金) 12:27:25.71ttp://www.haskell.org/
日本語サイト
ttp://www.sampou.org/cgi-bin/haskell.cgi
ttp://www.shido.info/hs/
過去ログ
関数型プログラミング言語Haskell
Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html
Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/
Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/
0232デフォルトの名無しさん
2011/10/22(土) 22:02:58.14リストのデータ構造の性質
haskellじゃなくても、リストを使えば先頭からしか辿らない
0233デフォルトの名無しさん
2011/10/22(土) 22:07:14.120234デフォルトの名無しさん
2011/10/22(土) 22:25:23.49たとえば [1..3] は 1 : (2 : (3 : [])) であり、
「リストを構成するデータ型」の値だ
そして、 : や [] はこのデータ型の「値構築子」だ( : は中置値構築子)
last 関数は、last [] = errorEmptyList "last"; last (x:xs) = ・・・
という形のパターンマッチを行う関数だ
last [1..3] は last (1: (2 : (3 : []) なので、
(x:xs) にパターンマッチし、x=1、xs=(2 : (3 : [])) と束縛する
リストに限らず、データ型の値を作ってる値構築子の引数(この場合は 1 や 2 など)は、
このようにパターンマッチさせて値構築子を剥がす事でしか参照できない
で、リスト 1 : (2 : (3 : [])) がこのようなネスト構造を成している以上、
ネスト構造を「順に剥がしていく」ことでしか中の値は参照できない
ちなみに、f (_:_:x:_) = という関数で f [1..3] などとして一気に x=3 と束縛しようとしても、
内部で順に値構築子を剥がす処理をしてパターンにマッチするかを調べるから同じ事
これを 「Haskellの出来」 というのなら、そうだね、としか言いようがない
0235デフォルトの名無しさん
2011/10/22(土) 22:55:21.45haskellの出来じゃない
配列と違って、リストはメモリ上に連続して並んでる保証はない
だから、先頭から順々に次に要素のアドレスを参照していくしかない
配列なら、連続して並んでるから、先頭から要素のサイズをステップ数として、希望の位置までアドレスの参照先をずらせば良い
c言語でも同じ事
(haskellで配列使った事ないから分からんが、配列と言うデータ構造の性質としてはO(1)になるはず)
0236デフォルトの名無しさん
2011/10/22(土) 22:56:21.45o要素一つのサイズ
0237SCHEME餃子 ◆8X2XSCHEME
2011/10/22(土) 23:06:30.13構文木の段階の情報と、実行時の段階のマシンコード (バイトコード) ではレイヤが違う話。
レイヤをまたいでうまいことやれば…というのは個別の実装の最適化をがんばってもらうしかない。
0238デフォルトの名無しさん
2011/10/22(土) 23:15:23.45それでじゃあ、この最適化があれば実装の出来がいいかって言われると
うーん
0239デフォルトの名無しさん
2011/10/22(土) 23:25:42.57うん?
ghciの話じゃないのか
ghcにO2オプション付ければ積極的に最適化されるから、
last [1..3] = 3
みたいに最適化されてんじゃないの?
0240デフォルトの名無しさん
2011/10/22(土) 23:44:29.49少なくとも GHC 7.0.3 ではされません
0241デフォルトの名無しさん
2011/10/22(土) 23:47:33.53Haskellや関数型プログラミングらしくなくて、むしろ気持ち悪いくらいなんだけど
0242デフォルトの名無しさん
2011/10/22(土) 23:54:35.79俺は、楽しいかどうかというより、
そういう発想が他のどういうところに活かされるのか気になる
0243デフォルトの名無しさん
2011/10/22(土) 23:56:32.370244デフォルトの名無しさん
2011/10/23(日) 00:00:25.87>>241 はFP的ではないと感じてるわけだから、
どの辺りがFP的か簡単にでも説明してあげないと堂堂回りになるよ
0245デフォルトの名無しさん
2011/10/23(日) 00:03:30.59の事ってのは通じてる?
Bird先生の本もこの系譜になると思うけども。
0246デフォルトの名無しさん
2011/10/23(日) 00:25:49.78普通はプログラミングパラダイムの方を思い浮かべる
0247デフォルトの名無しさん
2011/10/23(日) 00:30:01.52Function Programmingの略!
これが関数道の正しい道!
0248デフォルトの名無しさん
2011/10/23(日) 00:32:44.35>>186のどこが関数的?
0249デフォルトの名無しさん
2011/10/23(日) 00:41:48.580250デフォルトの名無しさん
2011/10/23(日) 01:26:52.91関数的とも手続き的手も言えん、なんとも分からん代物
0251デフォルトの名無しさん
2011/10/23(日) 01:42:08.77mainの最後を[2..100]と変えたらおかしくなることからして関数的でないことが分かる
それに関数的かどうかとは別に、プログラムとしても洗練されてない
fizzとbuzzの空文字列や関数fに数値を渡す設計はどうにかならなかったのかと思うし
fの中で文字列の比較をしてるのも酷い
Bird先生?難しい本を薦める前に添削してやれよと…
0252デフォルトの名無しさん
2011/10/23(日) 04:25:14.59Bird先生は別に要素レベルの演算までリストでやれと言ってるわけではないと思う。
lift n = (n,"")
fizz (n,s) = (n,s ++ if n `mod` 3 == 0 then "fizz" else "")
buzz (n,s) = (n,s ++ if n `mod` 5 == 0 then "buzz" else "")
fizzbuzz xs = map (buzz . fizz . lift) xs
くらいでも関数的と言っていいんじゃないか。
0253デフォルトの名無しさん
2011/10/23(日) 04:54:09.210254デフォルトの名無しさん
2011/10/23(日) 07:27:28.91洗練されたコード早く
0255デフォルトの名無しさん
2011/10/23(日) 07:46:21.09>>252
0256デフォルトの名無しさん
2011/10/23(日) 08:15:42.99それはBird先生の本を薦めていた人たちに言ってくれよ
俺は剰余を使ったつまらないのしか書けないから
しかし>>252も何がしたいのかよく分からないなw
0257デフォルトの名無しさん
2011/10/23(日) 08:32:01.870258デフォルトの名無しさん
2011/10/23(日) 08:49:31.00つListLike
0259デフォルトの名無しさん
2011/10/23(日) 11:08:00.97うん
そういうのを使って「標準ライブラリ」を大掃除して整理してほしいんだよ
そうすれば、外部ライブラリもそれに倣う
0260デフォルトの名無しさん
2011/10/23(日) 11:19:24.02そんだけ肥大化して硬直化してるんだろうな
少なくともfold/buid書き換えがstream fusion(笑)に変わるよか後で
Cabalのdependency hellが解決されるのと同じくらい(見込みが無い)ように思える
0261デフォルトの名無しさん
2011/10/23(日) 11:37:11.82今ある標準ライブラリはもう手を付けず deprecated にして、
真標準ライブラリを新たに作ればいいのにな
それか、標準ライブラリにバージョンを付けるとか
0262デフォルトの名無しさん
2011/10/23(日) 11:40:25.87Preludeはそういう鈍重な憂き目にあうのは、つまり、Prelude自動読み込みというアイデアがアウトだったのでは
0263デフォルトの名無しさん
2011/10/23(日) 11:47:36.18仕様が 2010 に変わる時にいっしょに整理しておくべきだったよな
0264デフォルトの名無しさん
2011/10/23(日) 11:51:42.420265デフォルトの名無しさん
2011/10/23(日) 12:12:23.800266デフォルトの名無しさん
2011/10/23(日) 18:53:15.42returnは別に汚点じゃない。
0267デフォルトの名無しさん
2011/10/23(日) 20:06:09.980268デフォルトの名無しさん
2011/10/23(日) 23:05:12.84Haskell版Boostをご所望か?
0269デフォルトの名無しさん
2011/10/23(日) 23:26:21.32ごめん、Boost とどう繋がるのか全く分からん
0270デフォルトの名無しさん
2011/10/24(月) 00:21:47.40うん。酔っぱらってた。
0271デフォルトの名無しさん
2011/10/24(月) 00:47:01.620272デフォルトの名無しさん
2011/10/25(火) 00:39:21.95Prelude> let a = reverse
で、:t a と :t reverse が互いに同様なのに、
Prelude> import List
Prelude List> let b = group
で、:t b と :t group が互いに違うのは何でだろ?
エロイ人教えて。
0273デフォルトの名無しさん
2011/10/25(火) 03:15:22.56たぶん、単相性制限とGHCiにおける型のデフォルト化の拡張の結果。
単相性制限
http://www.sampou.org/haskell/report-revised-j/decls.html#sect4.5.5
GHCiにおける型のデフォルト化の拡張
http://www.kotha.net/ghcguide_ja/latest/interactive-evaluation.html#extended-default-rules
0274デフォルトの名無しさん
2011/10/25(火) 11:19:01.55言語仕様が焼け太りしてきたな♪
0275デフォルトの名無しさん
2011/10/25(火) 11:25:06.280276デフォルトの名無しさん
2011/10/25(火) 22:45:52.30死んだ
0277デフォルトの名無しさん
2011/10/25(火) 22:47:07.73一つの生命が途絶えた
Perl忍者
Perl忍者の意志を継ぐものが現れるよ
新生
そう感じる
0278デフォルトの名無しさん
2011/10/25(火) 23:04:45.72ファンだったのに、、、
0279デフォルトの名無しさん
2011/10/26(水) 23:30:49.18これはいつ評価される(べき)か、とか考えつつデータ構造を作りながら、
ふとそう思った。
0280デフォルトの名無しさん
2011/10/26(水) 23:53:21.74捉え方は無限大とはいわないけど十色ぐらいはあると思う
0281デフォルトの名無しさん
2011/10/27(木) 00:09:47.16そう決めてしまうと
発想を狭めることにはなるかもしれないな
0282デフォルトの名無しさん
2011/10/27(木) 06:02:46.69ちがうよ
0283デフォルトの名無しさん
2011/10/27(木) 10:21:40.180284デフォルトの名無しさん
2011/10/27(木) 12:12:07.98発想はよさだろ
発想が狭くても良ければいい
お前みたいなやつはクソ
海外旅行経験300回未満のゴミが
"欧米では〜〜、海外では〜〜、視野を広める、心を広く、発想を広く、世界は広い、井の中の蛙、まだまだ甘かった
日本人は〜、コミュニケーションは大事、むこうでは〜〜、ボブがよ!ヘイ!ジョンとかブログに書く馴れ馴れしく”
とかほざいてるのとおなじ気持ち悪いんだよゴミ
なあゴミ
0285デフォルトの名無しさん
2011/10/27(木) 12:15:28.51海外旅行をすればHaskellがバリバリ書けるようになりますか?
0286デフォルトの名無しさん
2011/10/27(木) 12:31:24.60良い発想かどうかは、誰がどうやって判断するんだろ。。。
0287デフォルトの名無しさん
2011/10/27(木) 12:32:19.360288デフォルトの名無しさん
2011/10/27(木) 12:39:59.83そんなのは世界中のHaskellに関わり、
かつのその発想に関わる人間みんなが判断していくんだろ
そして、大多数の人に良い発想だと認められれば、
その発想が世の中に認められているということだ
ごく普通の当たり前のことだと思うが、そんなに疑問に思うことか
0289デフォルトの名無しさん
2011/10/27(木) 12:49:24.80パーサー実装はHaskellの練習としては手頃なのでお奨め。
0290デフォルトの名無しさん
2011/10/27(木) 12:56:12.28これを否定されてそんなに腹が立ったのかいw
0291デフォルトの名無しさん
2011/10/27(木) 12:57:24.900292デフォルトの名無しさん
2011/10/27(木) 13:00:13.59それより「発想」ってのが何かのトラウマのスイッチを押してしまったらしいよ
0293デフォルトの名無しさん
2011/10/27(木) 13:01:52.270294デフォルトの名無しさん
2011/10/27(木) 13:04:54.290295デフォルトの名無しさん
2011/10/27(木) 13:17:59.98全部一緒なんじゃなかろうな
0296デフォルトの名無しさん
2011/10/27(木) 13:36:35.90X: 関数型言語がいつまでもキチガイ誘蛾灯みたいなポジションなのも困るね
O: ハスケルがいつまでもキチガイ誘蛾灯みたいなポジションなのも困るね
0297デフォルトの名無しさん
2011/10/27(木) 19:14:05.00文学はいいので工学の話してください
0298デフォルトの名無しさん
2011/10/27(木) 23:19:35.930299デフォルトの名無しさん
2011/10/27(木) 23:47:18.79「できない」アプローチが「ある」っていう概念が理解できないから説明してくれろ
0300デフォルトの名無しさん
2011/10/28(金) 00:14:33.39>全部一緒なんじゃなかろうな
284〜296まで一人で自演乙
でも、こんな過疎スレで一時間ちょいで十レス以上とか、
もうちょっとリアリティってヤツを考えたほうがいいね。
0301デフォルトの名無しさん
2011/10/28(金) 02:56:26.22みたいな作法って持ってます?
ある組成式を受けとったら、その分子の平均質量とかマススペクトルとかを返してくれるような
プログラムを書いてみようかと思ったんだけど、まず基本となる原子のデータ型から作っていって、
data Atom = Atom { abbr::Char, abundance::Distributions }
type Distributions = [(Int,Double)]
とか定義しておいて、average :: Atom -> Doubleやspectrum :: Atom -> (Int -> Double)
みたいな関数を作り、組成式はtype Molecule = [(Atom,Int)]としてみようか、と考えています。
で、Atomを拡張してname::Stringみたいな値も格納しておこうか、と思いついたとき、
Atom型の値の中身をパターンマッチで分解している部分は全て書き直さなければならなくなります。
変更に弱いから、手探りでコーディングをしているときはパターンマッチによる分解は使うべきじゃない、ということで良いのでしょうか。
0302デフォルトの名無しさん
2011/10/28(金) 03:18:36.06とりあえず、その個別の問題に対しては、
data T1 = T1 { c :: Char }
data T2 = T2 { d :: Char, s :: String}
f T1{c = 'a' } = "c is 'a'"
f T1{c = c } = "c is not 'a': " ++ show c
g T2{d = 'a' } = "d is 'a'"
g T2{d = d } = "d is not 'a': " ++ show d
以上のパターンを用いることによって対処できる
さらに、
h t2@T2{d = 'b' } = t2{d = 'c', s ="foo" }
のようにasパターンと組み合わせることものできるから、かなりの柔軟性が確保できるはず。
0303302
2011/10/28(金) 03:20:39.58T1とT2は、別の型というよりも、変更前の型と変更後の型をシミュレートしていると考えて。
だから、このコードではcとdは別の識別子だけど、変更前と変更後で同じ識別子にすることができる。
0304デフォルトの名無しさん
2011/10/28(金) 07:47:46.60> Atom型の値の中身をパターンマッチで分解している部分
ここが元凶じゃないかな
Atom型の値の中身をパターンマッチで分解するのなら、
何の為に abbr 関数や abundance 関数を定義したの?
パターンマッチで分解するんじゃなく、
これらの関数を使って中身を取得すべきじゃないの?
パターンマッチだと型の構成を固めちゃうよ
ちなみに、見た目よく似た問題に Expression Problem というのがある
data X = A | B という型をパターンマッチで A B 仕分けしている関数が多くあり、
そこに新たに C という値構築子を追加したいが、修正すべき関数が多くて大変
なんとか楽にしたい、ついでにできれば再コンパイルしたくない
そういう場合なら、たとえばこことか日本語で分かりやすい
http://d.hatena.ne.jp/maoe/20101214/1292337923
0305デフォルトの名無しさん
2011/10/28(金) 08:16:42.39普通はデータ構築子をmodule外に非公開にすることで
内部構造を隠匿する
よくあるOOP言語ではclassが抽象データ型の単位だけど
Haskellだとmoduleになる
0306301
2011/10/28(金) 09:25:56.34haskellの入門書などではdata X = MkX Int Double Charなどとしておいて、
f (X i d c) = ...と記述することが「できる」とあったのですが、これって便利なのか?と疑問に思ったのです。
>>304確かにアクセッサ関数を定義しているので、型に何かを追加する可能性がある場合は
柔軟性を保てるのですが、例えば存在比を(Int,Double)のリストで表すよりもData.Mapで表す方がベターだと思った場合、
やっぱり変更先が多くなりそうになって嫌だなあと思った次第でして。
>>304のリンク先の方法がスマートに見えるので試してみたいと思います。
最終的には原子に限らず、平均値と分布を出せるようになりたいので、averageやspectrumをAtomだけに制限するのは良い手じゃなさそうです。
0307デフォルトの名無しさん
2011/10/28(金) 12:53:34.49> 例えば存在比を(Int,Double)のリストで表すよりもData.Mapで表す方がベターだと思った場合
そういう場合は、Data.Map 型を使ったコンテナに対するアクセス関数を公開して、
そのコンテナ内部で Data.Map 型を使っていることは隠蔽しておく
>>305 も同じ様なことをアドバイスしている
こうやって、データとそのユーザとの間にインターフェースを設けるのは、
Haskell に限らず、まず間違いなく全ての言語で共通する考え方
CICP 的に言えば「抽象の壁」だ
ちなみに、>>304 の後半で紹介した Expression Problem は、
少なくとも >>301 から読み取れる問題とは別ものと思われる
(応用できるかどうかは分からないけど)
0308デフォルトの名無しさん
2011/10/28(金) 12:54:58.72すまん
誤) CICP 的に言えば
正) SICP 的に言えば
0309デフォルトの名無しさん
2011/10/28(金) 18:25:33.57で作業をしていくための工夫という感じだな。ってね。安全な作業をするには必
要なんだってのもようやくわかった。
同時に感覚的なイメージでモナドを上手に例えて伝えるようなものがあまりない
のかもとも思ったかな。水中で普通のデジカメで撮影をするには防水ケースの中
に入れて使うけど、あの防水ケースっぽい働きなんだなってね。そんなアナロジー
を想像してしまったかな。
0310デフォルトの名無しさん
2011/10/28(金) 19:10:16.64> 同時に感覚的なイメージでモナドを上手に例えて伝えるようなものがあまりない
> のかもとも思ったかな。
確かにね
hage :: [Int]
hage = do
x <- [1..5]
when (x == 3) (fail "discard")
return x
こういうのだと、どの世界とどの世界に分けてるのか曖昧だし
明確に分けられたとしても、その世界に何かを閉じ込めているのとも違う気がする
0311デフォルトの名無しさん
2011/10/28(金) 20:14:47.390312デフォルトの名無しさん
2011/10/28(金) 20:59:44.73いや、たがら、そのリストモナドが分けた2つの世界は何と何か
という辺りが自分では上手く説明できないなぁと
0313デフォルトの名無しさん
2011/10/28(金) 21:06:31.22結果を渡される以外無関係ってと事だろう?
0314デフォルトの名無しさん
2011/10/28(金) 21:31:03.44>>310 のは実質これ
hage :: [Int]
hage = [1..5] >>= \x -> when (x == 3) (fail "discard") >> return x
>>313 の言う流儀というのは、結局
Monad クラスのインスタンスの定義方法、だよね
(>>= 関数をどう定義するか、return 関数をどう定義するか、など)
でもそれは、たとえばアローでも同じ事が言えて、
proc do内の世界はproc doの流儀に従ってる・・・
つまり Arrow クラスのインスタンスの定義方法がその流儀となる
じゃあ、アローもモナドと同じように、世界を2つに分けているのかな
分けているのなら、モナドが分ける世界とアローが分ける世界は何が違う?
そこまで考えて初めて、モナドが何をどう分けているのか、
ということの理解に繋がると思う
0315デフォルトの名無しさん
2011/10/28(金) 21:46:35.520316デフォルトの名無しさん
2011/10/28(金) 21:47:25.840317デフォルトの名無しさん
2011/10/29(土) 00:06:08.58なので、また探ってみたい。やっと面白いと思うことが増えてきた感じです。
arrowのことは他の理解を終えてから取っかかるよ。
実はRWHをようやく半分まで消化したところ
0318デフォルトの名無しさん
2011/10/29(土) 10:48:25.49他にこれは読んでおけ、このページは見ておけというものはありますか?
0320デフォルトの名無しさん
2011/10/29(土) 11:06:24.93Haskell Report
0321デフォルトの名無しさん
2011/10/29(土) 12:31:01.72ありがとうございます
そうですね、元の Haskell の仕様を読んでおくのは当然ですね
熟読します
0322デフォルトの名無しさん
2011/10/29(土) 14:25:06.170323デフォルトの名無しさん
2011/10/29(土) 14:44:46.62ありがとうございます
Webサイトや README をざっと見た感じ、自分でパーサーを作らなくても
extcore 自体を使って目的が達成できそうな気配なので、ちょっと試してみます
0324デフォルトの名無しさん
2011/10/29(土) 19:04:56.33core言語って何?
0325デフォルトの名無しさん
2011/10/29(土) 19:05:53.180326デフォルトの名無しさん
2011/10/29(土) 21:13:07.970327デフォルトの名無しさん
2011/10/29(土) 21:18:07.01どうした、いきなり
0328デフォルトの名無しさん
2011/10/30(日) 22:46:14.150329デフォルトの名無しさん
2011/10/30(日) 23:07:42.93IOモナドになるけど、余計なライブラリも使わず意外に簡単だったりする
0330デフォルトの名無しさん
2011/10/30(日) 23:23:54.14そうか。ありがとう。
0331デフォルトの名無しさん
2011/10/31(月) 07:50:06.70・・・ `a' is a rigid type variable bound by ・・・
この rigid type というのは何の分野の用語なの?
どういう状況のエラーなのか、もっと深く理解したい
■ このスレッドは過去ログ倉庫に格納されています