関数型プログラミング言語Haskell Part22
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2013/03/23(土) 12:34:19.09ttp://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/
Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
Part17 ttp://toro.2ch.net/test/read.cgi/tech/1325510368/
Part18 ttp://toro.2ch.net/test/read.cgi/tech/1331902463/
Part19 ttp://toro.2ch.net/test/read.cgi/tech/1340760070/
Part20 ttp://toro.2ch.net/test/read.cgi/tech/1350428908/
Part21 ttp://toro.2ch.net/test/read.cgi/tech/1358702176/
0552デフォルトの名無しさん
2013/06/10(月) 11:47:26.95(++) `on` show
compare `on` snd
0553デフォルトの名無しさん
2013/06/10(月) 11:59:19.810554548
2013/06/10(月) 13:12:14.00言葉が悪かったな、本当に済まなかった。
言いたかったことはこれ
初心者はPrelude禁止とか変な縛りはせず、
Preludeの中の関数の定義を読むか、
自分から書きなおした方がいいんじゃないか、勉強的に
関数型プログラミングをするのは、難しい問題を分解して
多くの簡単で小さな問題を解く関数を書くことではないか。
だからmapを使え。mapがなにしてるかわからないのなら
書きなおして身につける方がいい
僕は上の母語の日本語じゃない奴なので
変な文&正しくないマナーは許してくれ(汗
0555デフォルトの名無しさん
2013/06/10(月) 19:08:11.83ID:lZ0F4JgH!ありがとうございます。
出きるだけprelude関数を使いたくなかった理由はjavaやってる時に、
ずっとライブラリーを貼って付けるみたいな作業を感じたので。
それにしても、Haskell意外と面白いな。これからもっと勉強します。
0556デフォルトの名無しさん
2013/06/10(月) 20:17:18.37関数型の基本だから覚えるべし。
0557デフォルトの名無しさん
2013/06/10(月) 20:32:08.37ID:lZ0F4JgH!foldlって無限のリストでも使用できるんですよね。
ま〜take, drop, map, zip, filter位は何とか覚えるようにしてます。
Haskell覚えること多いな。
algbraic type は自分でdata使って独自の型を作れるのは分かったノですが,abstract data typeが理解できない。
既存のIntやBool型などブラックボックス化されてるのがそうなのですか?
0558デフォルトの名無しさん
2013/06/10(月) 21:43:32.16purelude は弾けても fuga は死にそうです‥‥
0559デフォルトの名無しさん
2013/06/10(月) 23:18:41.40本一冊読破すればそのような基本的な疑問はすべて解消すると思う
(まあ抽象データ型は関数型に限った話じゃないと思うが)
Prelude関数を自分で書いてみるのはHaskellの基本的なテクニックを学べる点では良い
ただプログラム書くのにいちいち定義してたら面倒だからライブラリがあるんでないのかね
これはどんな言語でも同じだと思うけど。さらにいえばファイル入出力とかのコードはどの言語でも
似たようなつまらないコードを書かざるをえない。こういう作業感はやることに依存すると思う。
0560デフォルトの名無しさん
2013/06/11(火) 04:43:03.72車輪の再発明にかまけてる時間があるのか
0561デフォルトの名無しさん
2013/06/11(火) 06:06:00.66「ふつうの・・・」では無理ね。
0562デフォルトの名無しさん
2013/06/11(火) 06:45:03.82再発明しかお金がもらえないんです
0563デフォルトの名無しさん
2013/06/11(火) 11:15:06.310564デフォルトの名無しさん
2013/06/11(火) 23:08:35.87pairUp [1,3,5]
はどういう結果になるのが正しいと思ってる?
0565デフォルトの名無しさん
2013/06/11(火) 23:26:39.31抽象データ型は代数とみなせるから代数データ型とも言う事があるというだけで2つは同じもの。
構造化プログラミングはプログラムの連続分解というものを導入する事で大規模ソフトウェアの
開発を可能にしたけれど、データ構造の変更とデータ構造を操作する手続きの変更に弱かった。
抽象データ型を導入することでその欠点を補いつつ構造化プログラミングが可能になった。
(プログラムの連続分解をするにあたって有害だったのがgoto文)
Haskellでは例えば昔話題になったオードリー・タンのperl6は構造化プログラミングを実践してた。
ただ、抽象データ型はあんまつかってなかったと思う。
0566デフォルトの名無しさん
2013/06/11(火) 23:33:20.870567デフォルトの名無しさん
2013/06/11(火) 23:41:09.190568デフォルトの名無しさん
2013/06/11(火) 23:48:13.300569デフォルトの名無しさん
2013/06/11(火) 23:55:19.69Haskellで構造化プログラミングをやったから大規模開発ができたというのが正しいと思う。
0570デフォルトの名無しさん
2013/06/12(水) 13:54:46.68知り合いの人は中学数学すらおぼつかないバカなのにHaskell使ってることを自慢してきます
どうすればいいでしょうか?
0571デフォルトの名無しさん
2013/06/12(水) 14:04:35.020572デフォルトの名無しさん
2013/06/12(水) 17:56:37.86くだらないことを質問するな
0573デフォルトの名無しさん
2013/06/12(水) 20:58:46.800574デフォルトの名無しさん
2013/06/12(水) 21:12:07.510575デフォルトの名無しさん
2013/06/13(木) 00:20:21.190576デフォルトの名無しさん
2013/06/13(木) 04:39:36.23ナンプレパズルを解くプログラム
0577デフォルトの名無しさん
2013/06/13(木) 10:51:56.41> ま〜take, drop, map, zip, filter位は何とか覚えるようにしてます。
> Haskell覚えること多いな。
いや、その辺は現代的なLispの影響を受けた言語の基本かと。
0578デフォルトの名無しさん
2013/06/13(木) 21:36:42.93解説サイト作れ
0579デフォルトの名無しさん
2013/06/14(金) 12:33:39.450580デフォルトの名無しさん
2013/06/14(金) 13:38:17.60おれは評価する
0581デフォルトの名無しさん
2013/06/14(金) 16:28:04.480582デフォルトの名無しさん
2013/06/14(金) 16:30:11.48お前575だろ
0583デフォルトの名無しさん
2013/06/15(土) 00:08:38.79俺も評価する
0584デフォルトの名無しさん
2013/06/15(土) 00:18:06.540585デフォルトの名無しさん
2013/06/15(土) 00:28:12.51こんな微妙なネタで被るところだった
0586デフォルトの名無しさん
2013/06/16(日) 03:18:07.640587デフォルトの名無しさん
2013/06/16(日) 08:26:58.96ID:F2SjiwBC!の下の方に、四色で彩られた四角形の描写があります。
color $ (Color3 (1.0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) 0 0)のColor3やVertex3はメソッドだと分かったノですが、
parse error on input `color' とでました。
何がいけないのでしょうか?
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
main :: IO ()
main = do
(progname, _) <- getArgsAndInitialize
createWindow "Display a screen"
displayCallback $= display
mainLoop
display :: IO ()
display = do
clear [ColorBuffer]
renderPrimitive Quads $ do
color $ (Color3 (1.0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) 0.2 0)
vertex $ (Vertex3 (0.2::GLfloat) 0.2 0)
vertex $ (Vertex3 (0.2::GLfloat) 0 0)
color $ (Color3 (0::GLfloat) 1 0)
vertex $ (Vertex3 (0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) (-0.2) 0)
~~~
flush
0588デフォルトの名無しさん
2013/06/16(日) 09:07:18.73コピペしてimportとmainを追加したらコンパイル通ったよ
(実行したらウィンドウシステムが落ちたけどたぶん俺の環境の問題)
コピペミスじゃないか?
0589デフォルトの名無しさん
2013/06/16(日) 16:07:27.56ID:F2SjiwBC!多分何処かにミスがあったのだと思います。コンパイーラーは通ったのですが、どうやってmainを呼べばいいんでしょうか?
今まではghciからmainを呼んでいたのですが。
Haskell ? ghc -package GLUT game.hs -o game. ?
[1 of 1] Compiling Main ( game.hs, game.o )
Linking game. ...
Haskell ? main
zsh: correct main to man [nyae]? n
zsh: command not found: main
0590デフォルトの名無しさん
2013/06/16(日) 17:10:28.040591デフォルトの名無しさん
2013/06/16(日) 21:09:33.37言い得て妙だな
(必要になるまで575の評価をしない)
0592デフォルトの名無しさん
2013/06/16(日) 21:24:19.88ID:F2SjiwBC!おお、ありがとうございます。
0593デフォルトの名無しさん
2013/06/17(月) 04:44:22.94叙述トリックだ
0594デフォルトの名無しさん
2013/06/17(月) 08:47:10.520595デフォルトの名無しさん
2013/06/17(月) 11:14:29.81具体的には、Eqのインスタンスを宣言するときに(==), (/=)のどちらかを実装するって話(すごH本、wikibooksで確認)
いきなりEqクラスのデフォルト実装が循環定義になってるのを見せられると一瞬面食らう
学習上であまり直感的じゃない部分だと思うんだけど
ググってもあまり悲鳴が上がってないのが不思議
(ブログを見ると「らしい」という曖昧に理解してる感がある文章に出会える)
0596デフォルトの名無しさん
2013/06/17(月) 11:48:08.06上からのフェロモンで動いてる昆虫そのもの
0597デフォルトの名無しさん
2013/06/17(月) 15:57:31.37(==)だけ実装してる場合
x /= y を簡約化すると
not (x == y) -- x /= y の定義
not False -- (==は実装済みなので) x == y = False だとして
True -- not の定義
というふうになる
(/=)だけ実装してる場合も同様
普通(デフォルト)は==の否定(not)は/=と定義されるよね(逆もまた然り)という
実装が与えられてるだけで、そんなの関係ねえと思う人は(==)も(/=)も定義すればよい
data Human = Human { age :: Int, sex :: Int }
instance Eq Human where
x == y = sex x == sex y -- 左辺と右辺の(==)は違う
x /= y = age x /= age y
Q. John(19)はMary(19)は同じ(==)人物か
A. いいえ
Q. じゃあ二人は違う(/=)人なのね
A. いいえ
Q. ぐぬぬ
ってなるけど(最小完全定義の説明にはなってないかな
0598デフォルトの名無しさん
2013/06/17(月) 16:13:40.07意図ということでいいと思うけどな。
で、排中律が成立しているか、みたいなチェックの枠組は言語にはないよ、と。
0599デフォルトの名無しさん
2013/06/17(月) 16:13:52.83最初見たときは戸惑った
これじゃあ無限に巡回するじゃないか、と
ただそこで深く悩むことはなく
そのあとに出てきた信号をインスタンスにする例で
すぐに理解できた
0600デフォルトの名無しさん
2013/06/17(月) 21:25:09.17ミスリードで思い出したけど
このリードって導くの意味のリードだったってつい最近まで知らんかったの思い出した
読むの方だと思ってたwwwwwww
0601デフォルトの名無しさん
2013/06/17(月) 23:04:10.610602デフォルトの名無しさん
2013/06/18(火) 00:10:00.880603デフォルトの名無しさん
2013/06/18(火) 00:58:21.30http://www2.gssm.otsuka.tsukuba.ac.jp/staff/kuno/lectures/12/2012-04-TopicsPL6.pdf
といっても、そうなると焦点がそこに絞られちゃうからこんな感じでよいのでは?
http://www.sampou.org/haskell/tutorial-j/io.html
0604デフォルトの名無しさん
2013/06/19(水) 00:25:45.13という理解でよろしいでしょうか?
0605デフォルトの名無しさん
2013/06/19(水) 06:29:26.340606デフォルトの名無しさん
2013/06/19(水) 07:13:57.60なぜ?
0607デフォルトの名無しさん
2013/06/19(水) 09:12:46.560608デフォルトの名無しさん
2013/06/19(水) 09:18:26.09本当にそうなら、作ればいいだけではないか。
0609デフォルトの名無しさん
2013/06/20(木) 22:59:37.42これがOKで
Prelude> product [x | x <- [1..10000] , mod x 10 /= 0 , mod x 10 /= 2 , mod x 10 /= 5]
これがNGなのは何故ですか?
Prelude> product [x | x <- [1..10000] , not $ (mod x 10) <- [0,2,5] ]
<interactive>:15:36: Parse error in pattern: mod
0610デフォルトの名無しさん
2013/06/20(木) 23:22:08.48[x | x <- [1..1000] , y <- [0,2,5], not $ (mod x 10 == y) ]
0611デフォルトの名無しさん
2013/06/20(木) 23:33:50.070612デフォルトの名無しさん
2013/06/20(木) 23:38:31.57・mod の構文が間違っている
・(mod ...) が Int 型とマッチングしない
・[x| x <- ...., y <- ....] は (x,y) の全組み合わせを生成して、重複を削除せずにxだけ並べる
0613デフォルトの名無しさん
2013/06/21(金) 00:09:06.83Prelude> product [x | x <- [1..10000], mod x 10 /= 0, mod x 10 /= 2, mod x 10 /= 5]
0614609
2013/06/21(金) 00:58:46.81代名詞が分かり辛かったですが、"これ"は上を指しています
>>612
:t mod で確かめましたが、mod での行き先(?)は Int とは限らないのですか…
では、
Prelude> :i Integral で
instance Integral Integer
instance Integral Int
とあるのにも関わらず、(mod ...) が [0,2,5] :: [Int]
の要素である Int 型として推論されないのはなぜですか?
ググる際のキーワードも教えていただけると有難いです
0615デフォルトの名無しさん
2013/06/21(金) 01:01:11.010616デフォルトの名無しさん
2013/06/21(金) 02:01:36.60リスト内包表記 [ x | x <- hoge ] の正体は hoge >>= \x -> [x]
だから<-の左辺でパターンマッチ例えば(x:xs)とか(x,y)を使える
だけど普通の関数と同様に(mod x 10)というパターンマッチは使えない
0617デフォルトの名無しさん
2013/06/23(日) 18:36:49.35モナド難しい!と思われた初心者をまた逃したな
0618デフォルトの名無しさん
2013/06/23(日) 19:34:36.60where fact-tail 1 acc = 1
fact-tail n acc = fact-tail (n - 1) (acc * n)
みたいに素直に再帰で書き下せるところをいちいち末尾再帰に書き換えるように
なってしまいました。
こういうのってプログラム見にくいんじゃないかなぁと思いますが、
どうでしょうか?
好きにしろって言われるかもしれませんが
0619デフォルトの名無しさん
2013/06/23(日) 19:39:39.27見にくくなるかなぁと思いながら、それでもわざわざ末尾再帰にするくらいだから、
パフォーマンスの向上を狙っているのだと思う。
それが、「どれほどの」向上に繋がっているのか正しく理解しているのなら、
それでいいんでないか?
トレードオフでパフォーマンス側をとったというだけのことだから。
どれほどの向上なんだろ? という状態だったら、直ちに調査してみることを勧める。
0620デフォルトの名無しさん
2013/06/23(日) 20:13:36.120621デフォルトの名無しさん
2013/06/23(日) 20:32:23.730622デフォルトの名無しさん
2013/06/24(月) 02:23:24.02出力されるコードが末尾再帰になるようにプログラムを帰納するテクニックがある
別の言い方をすると、出力の一覧を見てコードを書くときに、頭を使わずに同じ手順でコードを書くときは、末尾再帰の方が楽な場合がある
(手は猛烈に動かすが、頭は使わないという意味で)
0623デフォルトの名無しさん
2013/06/24(月) 12:41:37.000624デフォルトの名無しさん
2013/06/24(月) 15:01:35.610625デフォルトの名無しさん
2013/06/24(月) 19:36:40.75実行効率で違いはあるのでしょうか。
data D = D { x :: Int, y :: Int, z :: Int }
d = D 1 2 3
{方法1} d' = D 5 6 7
{方法2} d' = d { x = 5, y = 6, z = 7}
部分的に更新するのではなく、全てのフィールドの値を更新するとして、です。
GHC のバージョンは 7.6.3 です。
0626デフォルトの名無しさん
2013/06/24(月) 20:44:50.76違いはない。
コンパイルの途中で同じコードになる。
0627デフォルトの名無しさん
2013/06/24(月) 21:48:17.00ありがとうございました。
0628デフォルトの名無しさん
2013/06/24(月) 22:43:19.95不安なら、中間コードを生成して中を覗けばいいと思う
0629デフォルトの名無しさん
2013/06/25(火) 12:57:13.870630デフォルトの名無しさん
2013/06/25(火) 19:44:03.760631デフォルトの名無しさん
2013/06/25(火) 19:54:39.46うろ覚え
0632デフォルトの名無しさん
2013/06/25(火) 20:22:43.95メモリ消費量的には余り変わらないという話じゃない?
0633デフォルトの名無しさん
2013/06/25(火) 20:34:26.43実際バリバリ使ってる人達はその辺どうしてるんでしょ
0634デフォルトの名無しさん
2013/06/25(火) 21:59:34.70>>632
>素朴な実装だと再帰の深さ分だけサンクをヒープに作るので
それは末尾再帰とは直交した問題
末尾再帰にした上で、サンクを作らないようにseqや!を使えばいいだけ
0635デフォルトの名無しさん
2013/06/25(火) 22:21:52.19思ったより進化してないなあ
0636デフォルトの名無しさん
2013/06/25(火) 22:49:05.800637618
2013/06/26(水) 00:17:25.70>>621
>>622
見難くないならまぁいいかな。
ご指摘の点を読み返してみて、自分はその関数がどういうものかという定義で
考えているのではなく、CやJavaのforループでカウンタと累積変数を動かしているのを
頭を使わず末尾再帰に書き下しているのだと思う。
できるだけfoldを使えるように精進するよ。
0638618
2013/06/26(水) 00:35:50.85factだと自明すぎて例として不適切だったでしょうか
いちおう繰り返しを行う関数を作るときは、必要な引数を受ける名前を定義して、
内部で末尾再帰のカウンタと累積変数をもちいた定義を行うということを示したつもりでした。
これでは動かんというのならごめんなさい。
Haskell慣れてないんです。
特にwhereのかかる範囲とか。
lisp、schemeの括弧が懐かしいです。
0639デフォルトの名無しさん
2013/06/26(水) 01:41:38.280640デフォルトの名無しさん
2013/06/26(水) 06:22:49.98この間の放送大学の「データ構造とプログラミング 9 再帰」見てようやく理解した。
0641デフォルトの名無しさん
2013/06/26(水) 07:21:21.31Prologなんかだと、末尾再帰ができていない処理系は使い物にならないし、
末尾再帰を意識して書かないと、動かないこともある。Prologの場合は、
末尾以前の全てのサブゴールの決定性が問われるとか、特殊な条件が付くが、
Haskellだとどうなのか、とかの理解は必要だと思う。
0642デフォルトの名無しさん
2013/06/26(水) 09:43:03.340643デフォルトの名無しさん
2013/06/26(水) 10:04:14.100644641
2013/06/26(水) 17:06:31.770645デフォルトの名無しさん
2013/06/26(水) 18:09:07.830646デフォルトの名無しさん
2013/06/26(水) 20:16:06.110647デフォルトの名無しさん
2013/06/26(水) 20:35:30.04shemeの継続?
0648デフォルトの名無しさん
2013/06/26(水) 21:10:53.39別の言い方をすれば、何を以って末尾再帰だと断定できる?
最後に自分自身を「呼び出す」ような形になっている、という言い方はできないよね。
関数を呼ぶのは評価が行われる時だから、引数の方が後に呼び出されるかもしれないし。
0649デフォルトの名無しさん
2013/06/26(水) 23:34:33.45C#とHaskellの使い分けの方針とかありますか?
0650デフォルトの名無しさん
2013/06/26(水) 23:56:54.050651デフォルトの名無しさん
2013/06/27(木) 00:13:46.56C# と同様に、極限まで処理速度を求められる分野以外なら何でもいい。
「言語」として向いている分野というのは特に無い。
使い分ける必要はなく、使い慣れたものを使えばいい。
0652デフォルトの名無しさん
2013/06/27(木) 07:56:45.02f x = f ...
みたいに、右辺の一番外側が自分自身を呼んでいればいい
ただし、caseとlet(や、構文糖であるifとwhere)が挟まっていてもok
f x = case x of [] -> 1; hd:tl -> f tl
みたいに
この形でなくても末尾再帰になることもあって、例えば
f x = putStrLn x >> f
だと、一番外側の呼び出しは(>>)だけど、IOモナドの(>>)ならfを一番外側で呼ぶので、
間接的に末尾再帰になる
■ このスレッドは過去ログ倉庫に格納されています