関数型プログラミング言語 Haskell について語るスレです。
haskell.org (公式サイト)
https://www.haskell.org/
日本Haskellユーザーグループ
https://haskell.jp/
前スレ
関数型プログラミング言語Haskell Part31
https://mevius.5ch.net/test/read.cgi/tech/1506447188/
探検
関数型プログラミング言語Haskell Part32
■ このスレッドは過去ログ倉庫に格納されています
2019/01/29(火) 09:05:47.90ID:gJP/u7IJ
169デフォルトの名無しさん
2019/02/22(金) 19:43:58.95ID:LKaW/yz7 >>168
foldlなんて単なるループみたいなもんだし
今どきJavaでもやるくらい
分かるまでは変に抽象化しないで、具体例で考えるといいよ
folder_left f a [a1 a2 a3]
じゃなくて
folder_left (+) 0 [1, 2, 3]
で考えるとか
そしたら
folder_left f (f a a1) [a2, a3]は
folder_left (+) ((+) 0 1) [2, 3]になる
要は最初に
int sum = 0
for(int a : xs) sum = sum + a
と書くのと変わらない
sumへの蓄積を、変数への再代入ではなく次の関数への引数として書いてるだけ
どちらかというと、いわゆる関数型っぽいのはこういうのよりfoldrでリスト作ったりするときの方かな
foldlなんて単なるループみたいなもんだし
今どきJavaでもやるくらい
分かるまでは変に抽象化しないで、具体例で考えるといいよ
folder_left f a [a1 a2 a3]
じゃなくて
folder_left (+) 0 [1, 2, 3]
で考えるとか
そしたら
folder_left f (f a a1) [a2, a3]は
folder_left (+) ((+) 0 1) [2, 3]になる
要は最初に
int sum = 0
for(int a : xs) sum = sum + a
と書くのと変わらない
sumへの蓄積を、変数への再代入ではなく次の関数への引数として書いてるだけ
どちらかというと、いわゆる関数型っぽいのはこういうのよりfoldrでリスト作ったりするときの方かな
170デフォルトの名無しさん
2019/02/22(金) 19:47:35.11ID:ioyynd1U >>169
まったくわからない
例題載ってるとこにも似たようなことは書いてあるんだけども
ループで書くならすぐ終わる話だけど
ややこしすぎてイメージがつかめない
イメージがつかめたらその時点で理解終了なんだけど
まったくわからない
例題載ってるとこにも似たようなことは書いてあるんだけども
ループで書くならすぐ終わる話だけど
ややこしすぎてイメージがつかめない
イメージがつかめたらその時点で理解終了なんだけど
171デフォルトの名無しさん
2019/02/22(金) 19:51:15.80ID:ioyynd1U a2とa3が分離されそうなことはわかるんだけども
folder_left f (f a a1) [a2 a3]
^^^^
こいつがどこ行くのっていうのと
どこをどうやったら()で括られることになるのかイメージできない
folder_left f (f a a1) [a2 a3]
^^^^
こいつがどこ行くのっていうのと
どこをどうやったら()で括られることになるのかイメージできない
172デフォルトの名無しさん
2019/02/22(金) 20:17:22.94ID:LKaW/yz7 >>171
folder_left f (f a a1) [a2, a3]
になるところまではわかるんだよね?
そしたらまず括弧の中から先に計算するのはどの言語も普通だよね
だから先に(f a a1)の答えが出る
fは引数を2つとる関数だから、答えを出すのに支障はないよね
ここで(f a a1)の計算結果をz1としようか
そしたら上の式は
folder_left f z1 [a2, a3]になるよね?
そうすると、f、z1、[a2, a3]の3つの引数を使って、folder_leftがまた呼び出されるのがわかる?ここが再帰ね
folder_leftの定義は2つあるけど、[a2 a3]は空リスト([])じゃないから、下の
folder_left f a (x:xs)の方が呼ばれるよね?
ここでaはz1、xはa2、xsは [a3]だよね
だからベタで書くと
folder_left f (f z1 a2) [a3]になるよね?
同じように括弧の中が先に計算されるから、(f z1 a2)をz2としようか
そしたら
folder_left f z2 [a3]となる
また全く同じようにfolder_leftを呼び出すと、次は
folder_left f (f z2 a3) []となる
そして同じように(f z2 a3)をz3とすると、
folder_left f z3 []と書ける
ここでまたまたfolder_leftを呼び出してるわけだけど、最後のリストが空リストだよね
だからfolder_leftの2つの定義の内、上の方のfolder_left _ a [] = aが呼ばれる
上から順に呼び出し条件を見てるからね
ここでaはz3のことだから、最終的にz3が答えになる
じゃあz3が何かっていうと、(f z2 a3)だよね。そしてz2が何かっていうと、(f z1 a2)だよね
つまりz3は(f (f z1 a2) a3)のことだ
そして最後にz1は(f a a1)だから、結局
z3 == f (f (f a a1) a2) a3となる
これでどうだ
folder_left f (f a a1) [a2, a3]
になるところまではわかるんだよね?
そしたらまず括弧の中から先に計算するのはどの言語も普通だよね
だから先に(f a a1)の答えが出る
fは引数を2つとる関数だから、答えを出すのに支障はないよね
ここで(f a a1)の計算結果をz1としようか
そしたら上の式は
folder_left f z1 [a2, a3]になるよね?
そうすると、f、z1、[a2, a3]の3つの引数を使って、folder_leftがまた呼び出されるのがわかる?ここが再帰ね
folder_leftの定義は2つあるけど、[a2 a3]は空リスト([])じゃないから、下の
folder_left f a (x:xs)の方が呼ばれるよね?
ここでaはz1、xはa2、xsは [a3]だよね
だからベタで書くと
folder_left f (f z1 a2) [a3]になるよね?
同じように括弧の中が先に計算されるから、(f z1 a2)をz2としようか
そしたら
folder_left f z2 [a3]となる
また全く同じようにfolder_leftを呼び出すと、次は
folder_left f (f z2 a3) []となる
そして同じように(f z2 a3)をz3とすると、
folder_left f z3 []と書ける
ここでまたまたfolder_leftを呼び出してるわけだけど、最後のリストが空リストだよね
だからfolder_leftの2つの定義の内、上の方のfolder_left _ a [] = aが呼ばれる
上から順に呼び出し条件を見てるからね
ここでaはz3のことだから、最終的にz3が答えになる
じゃあz3が何かっていうと、(f z2 a3)だよね。そしてz2が何かっていうと、(f z1 a2)だよね
つまりz3は(f (f z1 a2) a3)のことだ
そして最後にz1は(f a a1)だから、結局
z3 == f (f (f a a1) a2) a3となる
これでどうだ
173デフォルトの名無しさん
2019/02/22(金) 20:22:50.89ID:ioyynd1U174デフォルトの名無しさん
2019/02/22(金) 20:30:54.11ID:LKaW/yz7 >>173
そこらへんは評価戦略の話であって別件だね
再帰の本質ではないよ
Haskellといえば遅延評価みたいなところがあるから混乱しやすいけどね
上で言うならz3こと(f (f (f a a1) a2) a3)を、最後までこの形で持って行って、最後にまとめて計算するのが遅延評価
上で書いたみたく適宜評価していくのが正格評価
Haskellだとfolder_leftは二種類あって、
遅延評価版がfoldl
正格評価版がfoldl'
ぶっちゃけ左畳み込みに関してはfoldlを使うことはない
全部foldl'でいい
そこらへんは評価戦略の話であって別件だね
再帰の本質ではないよ
Haskellといえば遅延評価みたいなところがあるから混乱しやすいけどね
上で言うならz3こと(f (f (f a a1) a2) a3)を、最後までこの形で持って行って、最後にまとめて計算するのが遅延評価
上で書いたみたく適宜評価していくのが正格評価
Haskellだとfolder_leftは二種類あって、
遅延評価版がfoldl
正格評価版がfoldl'
ぶっちゃけ左畳み込みに関してはfoldlを使うことはない
全部foldl'でいい
175デフォルトの名無しさん
2019/02/23(土) 00:41:48.52ID:RiBir1w3 カリー化関数の意図がわからん
sum_of :: (Integer -> Integer, Integer, Integer) -> Integer
sum_of (f, n, m)
| n > m = 0
| otherwise = f n + sum_of (f, n + 1, m)
これはわかる
sum_of' :: (Integer -> Integer) -> Integer -> Integer -> Integer
sum_of' f n m
| n > m = 0
| otherwise = f n + sum_of' f (n + 1) m
どう見ても書き換えただけにしか見えないんだけどこれ意味あって書いてるのかな
カリー化って引数可変で動作する関数を定義するためのものって理解したけど
後者にはそんな意図が含まれてるように見えない
sum_of :: (Integer -> Integer, Integer, Integer) -> Integer
sum_of (f, n, m)
| n > m = 0
| otherwise = f n + sum_of (f, n + 1, m)
これはわかる
sum_of' :: (Integer -> Integer) -> Integer -> Integer -> Integer
sum_of' f n m
| n > m = 0
| otherwise = f n + sum_of' f (n + 1) m
どう見ても書き換えただけにしか見えないんだけどこれ意味あって書いてるのかな
カリー化って引数可変で動作する関数を定義するためのものって理解したけど
後者にはそんな意図が含まれてるように見えない
176デフォルトの名無しさん
2019/02/23(土) 02:34:37.24ID:hS0A7KKk >>175
やってるのは数式で書くと Σ[i=n..m] f(i) か
再帰をちょっと具体的に書き下さないと何のsumかわからんかった
それで多分やりたいのは
こういう風に個別の総和関数が手軽に作れますよみたいな話だと思う
タプルで定義されてるとこういう風にはいかない
(書けないことはないけどめんどくさい)
sumOfTwice :: Integer -> Integer -> Integer
sumOfTwice = sum_of (*2)
ここで(*2)とかできるのも
(*) :: Integer -> Integer -> Integer
がカリー化されてるおかげ
こういうのを部分適用と言って可変長引数とは異なる概念
やってるのは数式で書くと Σ[i=n..m] f(i) か
再帰をちょっと具体的に書き下さないと何のsumかわからんかった
それで多分やりたいのは
こういう風に個別の総和関数が手軽に作れますよみたいな話だと思う
タプルで定義されてるとこういう風にはいかない
(書けないことはないけどめんどくさい)
sumOfTwice :: Integer -> Integer -> Integer
sumOfTwice = sum_of (*2)
ここで(*2)とかできるのも
(*) :: Integer -> Integer -> Integer
がカリー化されてるおかげ
こういうのを部分適用と言って可変長引数とは異なる概念
177デフォルトの名無しさん
2019/02/23(土) 02:59:05.43ID:RiBir1w3 >>176
(*2)の意味わからなくて前後調べたら演算子をカリー化できるとかあって
やっと意味わかったありがとう
しかも例題の先の先の方に有効な利用法書いてあったけど
なんかどうもサイトの進め方と合わないなー・・変えるかー
こんなこと書いてもなんか意味あんのだから何なんみたいな悶々パターンが多すぎる
とても簡単ですとか書いてあったら相当難しいフラグ確定
考え方が違うんだろうな
(*2)の意味わからなくて前後調べたら演算子をカリー化できるとかあって
やっと意味わかったありがとう
しかも例題の先の先の方に有効な利用法書いてあったけど
なんかどうもサイトの進め方と合わないなー・・変えるかー
こんなこと書いてもなんか意味あんのだから何なんみたいな悶々パターンが多すぎる
とても簡単ですとか書いてあったら相当難しいフラグ確定
考え方が違うんだろうな
178デフォルトの名無しさん
2019/02/23(土) 06:50:54.90ID:T/+XuHA6 考え方を変えるのが関数型を学ぶ一番の目的だと思うけど、
合わないなら関数型あきらめればいいじゃん。
うちは論理型言語に全く馴染めなくて、それに時間使うのやめた。
合わないなら関数型あきらめればいいじゃん。
うちは論理型言語に全く馴染めなくて、それに時間使うのやめた。
179デフォルトの名無しさん
2019/02/23(土) 10:50:43.56ID:7gjHPQsv そうじゃない
人を信じるのをあきらめて嘘を嘘と批判する
とても簡単ですと言った奴は嘘つきのクズであると
人を信じるのをあきらめて嘘を嘘と批判する
とても簡単ですと言った奴は嘘つきのクズであると
180デフォルトの名無しさん
2019/02/23(土) 13:04:48.43ID:RiBir1w3 しかしいいサイト全然ないなどうしたもんか
お前らどうやって習得したのよこんな難解な言語
お前らどうやって習得したのよこんな難解な言語
181デフォルトの名無しさん
2019/02/23(土) 13:35:58.14ID:7gjHPQsv 例えばC#とF#の考え方は変わらないし
考え方を変えるというのも嘘だな
嘘に気付くのに1日かかるやつと5年以上かかるやつの差は大きい
考え方を変えるというのも嘘だな
嘘に気付くのに1日かかるやつと5年以上かかるやつの差は大きい
182デフォルトの名無しさん
2019/02/23(土) 14:01:38.38ID:E9HQXzXo >嘘に気付くのに
ひどい世の中だな
ひどい世の中だな
183デフォルトの名無しさん
2019/02/23(土) 17:11:04.23ID:RiBir1w3 Prelude> let foo n = ¥x -> x * n
Prelude> :t foo
foo :: Num a => a -> a -> a
Prelude> let foo10 = foo 10
Prelude> :t foo10
foo10 :: Integer -> Integer
Prelude> foo10 10
100
Prelude> foo10 20
200
Prelude> let foo100 = foo 100
Prelude> foo100 10
1000
Prelude> foo100 20
2000
Prelude> let foo5 = foo 5
Prelude> foo5 10
50
Prelude> foo5 20
100
Prelude> :t foo (1.234 :: Double)
foo (1.234 :: Double) :: Double -> Double
Prelude> :t foo
foo :: Num a => a -> a -> a
Prelude> let foo10 = foo 10
Prelude> :t foo10
foo10 :: Integer -> Integer
Prelude> foo10 10
100
Prelude> foo10 20
200
Prelude> let foo100 = foo 100
Prelude> foo100 10
1000
Prelude> foo100 20
2000
Prelude> let foo5 = foo 5
Prelude> foo5 10
50
Prelude> foo5 20
100
Prelude> :t foo (1.234 :: Double)
foo (1.234 :: Double) :: Double -> Double
184デフォルトの名無しさん
2019/02/23(土) 17:12:26.05ID:RiBir1w3 >>183のクロージャの説明がさっぱりわからない
関数を生成する関数を簡単に作ることができるって言ってるんだけど
やってることは定義を繰り返してるだけでちっとも生成してない
どういう意味で関数を生成したって言ってるんだろ・・
Stringで関数生成してevalで評価しましただったらわかるんだけど、これ違うよね
それともhaskellの場合は関数定義は関数生成としているのか・・わからん
一体これは何が言いたいのか・・
実はどうでもいいことで気にしなくてもいいなら納得するんだけども
関数を生成する関数を簡単に作ることができるって言ってるんだけど
やってることは定義を繰り返してるだけでちっとも生成してない
どういう意味で関数を生成したって言ってるんだろ・・
Stringで関数生成してevalで評価しましただったらわかるんだけど、これ違うよね
それともhaskellの場合は関数定義は関数生成としているのか・・わからん
一体これは何が言いたいのか・・
実はどうでもいいことで気にしなくてもいいなら納得するんだけども
185デフォルトの名無しさん
2019/02/23(土) 17:31:29.38ID:YUL1Jv8G 前スレに比べて明らかに初心者が多いのは何故だ
186デフォルトの名無しさん
2019/02/23(土) 17:37:12.35ID:5fn4St+r またHaskellのせいにしてるの?
以下は同等のJavaScriptだけど。
let foo = n => x => x * n;
let foo10 = foo(10);
foo10(10);
//=> 100
foo10(20);
//=> 200
let foo100 = foo(100);
foo100(10);
//=> 1000
foo100(20);
//=> 2000
let foo5 = foo(5);
foo5(10);
//=> 50
foo5(20);
//=> 100
てか何の言語なら知ってるんだっけ?
以下は同等のJavaScriptだけど。
let foo = n => x => x * n;
let foo10 = foo(10);
foo10(10);
//=> 100
foo10(20);
//=> 200
let foo100 = foo(100);
foo100(10);
//=> 1000
foo100(20);
//=> 2000
let foo5 = foo(5);
foo5(10);
//=> 50
foo5(20);
//=> 100
てか何の言語なら知ってるんだっけ?
187デフォルトの名無しさん
2019/02/23(土) 17:46:51.51ID:RiBir1w3 >>186
そうじゃなくてこれ関数定義だけで生成なんかしてないよね?って話
ぱっと見パスしてもいいようなどうでもいいことにも見える
そうであれば次に行く
どうもHaskellは納得いかないことがあまりにも多いんだ
文化の違いなのか考え方の違いなのかわからんけど
CかObj-CかSmalltalk-80/VisualWorksで
そうじゃなくてこれ関数定義だけで生成なんかしてないよね?って話
ぱっと見パスしてもいいようなどうでもいいことにも見える
そうであれば次に行く
どうもHaskellは納得いかないことがあまりにも多いんだ
文化の違いなのか考え方の違いなのかわからんけど
CかObj-CかSmalltalk-80/VisualWorksで
188デフォルトの名無しさん
2019/02/23(土) 17:59:11.82ID:5fn4St+r Cは実行時関数生成能力ないから仕方ないけど…
let foo10 = foo 10
は関数を返す関数fooに10を渡して、
関数(¥x -> x * 10)を得て(これが、ここが「生成」)
それにfoo10って名前を付けてるって理解は無理?
あなたこれまでに¥x -> x * 10って関数定義した覚えある?書いた覚えがあるのは¥x -> x * nでしょ?
まあ次行け次。
let foo10 = foo 10
は関数を返す関数fooに10を渡して、
関数(¥x -> x * 10)を得て(これが、ここが「生成」)
それにfoo10って名前を付けてるって理解は無理?
あなたこれまでに¥x -> x * 10って関数定義した覚えある?書いた覚えがあるのは¥x -> x * nでしょ?
まあ次行け次。
189デフォルトの名無しさん
2019/02/23(土) 18:05:45.67ID:RiBir1w3190デフォルトの名無しさん
2019/02/23(土) 18:08:48.44ID:7gjHPQsv C++だったらtemplate引数として渡したら定義で、コンストラクタに渡したら生成
静的と動的がわかるのが前提だからわからないならpythonかjavascriptから始めるべき
静的と動的がわかるのが前提だからわからないならpythonかjavascriptから始めるべき
191デフォルトの名無しさん
2019/02/23(土) 18:12:36.80ID:RiBir1w3192デフォルトの名無しさん
2019/02/23(土) 18:18:49.99ID:5fn4St+r >>189
> foo10は結局のところ ¥x->x*n を呼び出してるだけじゃないの?
Prelude> foo10 10
100
とかのこと言ってるんなら
let foo10 = foo 10
で生成した関数(¥x -> x * 10)を呼び出してるつまり
(¥x -> x * 10) 10
100
> ¥x->x*10って関数を生成してないよね?
してるよ
let foo10 = foo 10 の foo 10の部分で。
(生成のタイミングは今回置いとくとして)
> foo10は結局のところ ¥x->x*n を呼び出してるだけじゃないの?
Prelude> foo10 10
100
とかのこと言ってるんなら
let foo10 = foo 10
で生成した関数(¥x -> x * 10)を呼び出してるつまり
(¥x -> x * 10) 10
100
> ¥x->x*10って関数を生成してないよね?
してるよ
let foo10 = foo 10 の foo 10の部分で。
(生成のタイミングは今回置いとくとして)
193デフォルトの名無しさん
2019/02/23(土) 18:28:43.67ID:RiBir1w3194デフォルトの名無しさん
2019/02/23(土) 18:29:48.03ID:7gjHPQsv templateとコンストラクタとメソッドの考え方
関数と関数と関数の考え方
変わったのは見た目だけ
関数と関数と関数の考え方
変わったのは見た目だけ
195デフォルトの名無しさん
2019/02/23(土) 18:33:42.53ID:RiBir1w3 >>194
C++は全く知らないのでそっちはなんとも
C++は全く知らないのでそっちはなんとも
196デフォルトの名無しさん
2019/02/23(土) 18:51:02.51ID:RiBir1w3 早速詰まった何を言ってるのかわからん
一般に、関数を呼び出す場合、関数を評価するための環境は空リストです。
最初に、引数がこの環境に追加されます。let で定義される局所変数もこの環境に追加されます。
もしも、環境に該当する変数が存在しない場合は大域変数を参照します。
たとえば、foo 5 と呼び出すと環境は次のようになります。
foo 5 ==> 環境 : [(n, 5)]
ghciで実行
Prelude> let foo n = ¥x -> x * n
Prelude> foo 5
<interactive>:2:1: error:
• No instance for (Show (Integer -> Integer))
arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
• In a stmt of an interactive GHCi command: print it
Prelude>
そりゃそうだよねぇ・・
なんなんだろう何が言いたいのかさっぱりわからない
本当にこんな説明でみんな理解してったの?
一般に、関数を呼び出す場合、関数を評価するための環境は空リストです。
最初に、引数がこの環境に追加されます。let で定義される局所変数もこの環境に追加されます。
もしも、環境に該当する変数が存在しない場合は大域変数を参照します。
たとえば、foo 5 と呼び出すと環境は次のようになります。
foo 5 ==> 環境 : [(n, 5)]
ghciで実行
Prelude> let foo n = ¥x -> x * n
Prelude> foo 5
<interactive>:2:1: error:
• No instance for (Show (Integer -> Integer))
arising from a use of ‘print’
(maybe you haven't applied a function to enough arguments?)
• In a stmt of an interactive GHCi command: print it
Prelude>
そりゃそうだよねぇ・・
なんなんだろう何が言いたいのかさっぱりわからない
本当にこんな説明でみんな理解してったの?
197デフォルトの名無しさん
2019/02/23(土) 19:26:38.79ID:hS0A7KKk >>196
そこクロージャの説明のとこでしょ? 読み飛ばしていいと思うよ
手元にHaskellの入門書何冊かあるけど目次や索引にクロージャ無いし
純粋関数型言語でありデフォルトで関数がカリー化されているHaskellに
クロージャとかいう概念は別に要らないと思う
部分適用便利だねってことがわかればおk
そこクロージャの説明のとこでしょ? 読み飛ばしていいと思うよ
手元にHaskellの入門書何冊かあるけど目次や索引にクロージャ無いし
純粋関数型言語でありデフォルトで関数がカリー化されているHaskellに
クロージャとかいう概念は別に要らないと思う
部分適用便利だねってことがわかればおk
198デフォルトの名無しさん
2019/02/23(土) 19:34:16.40ID:RiBir1w3199デフォルトの名無しさん
2019/02/23(土) 20:14:35.45ID:RiBir1w3 データ型の定義まで来た
なんというかやっぱりこのサイトこれからhaskell入門の人にはどうでもいい余計なこと書きすぎなんじゃ・・
と思った
なんというかやっぱりこのサイトこれからhaskell入門の人にはどうでもいい余計なこと書きすぎなんじゃ・・
と思った
200デフォルトの名無しさん
2019/02/23(土) 21:08:00.52ID:RiBir1w3 do構文がIO型だからこのように書ける・・というのがどうもしっくりこないけど
都合上こうするしかなかったってだけの話で特別な意味はないのかな
calc :: IO ()
calc = do
putStr "Input Integer1 > "
x <- readLn :: IO Integer
putStr "Input Integer2 > "
y <- readLn :: IO Integer
let a = x + y
b = x - y
c = x * y
d = x `div` y
n1 = show x
n2 = show y
putStrLn (n1 ++ "+" ++ n2 ++ "=" ++ show a)
putStrLn (n1 ++ "-" ++ n2 ++ "=" ++ show b)
putStrLn (n1 ++ "*" ++ n2 ++ "=" ++ show c)
putStrLn (n1 ++ "/" ++ n2 ++ "=" ++ show d)
都合上こうするしかなかったってだけの話で特別な意味はないのかな
calc :: IO ()
calc = do
putStr "Input Integer1 > "
x <- readLn :: IO Integer
putStr "Input Integer2 > "
y <- readLn :: IO Integer
let a = x + y
b = x - y
c = x * y
d = x `div` y
n1 = show x
n2 = show y
putStrLn (n1 ++ "+" ++ n2 ++ "=" ++ show a)
putStrLn (n1 ++ "-" ++ n2 ++ "=" ++ show b)
putStrLn (n1 ++ "*" ++ n2 ++ "=" ++ show c)
putStrLn (n1 ++ "/" ++ n2 ++ "=" ++ show d)
201デフォルトの名無しさん
2019/02/23(土) 21:24:41.95ID:24PtBhaW202デフォルトの名無しさん
2019/02/23(土) 21:25:53.99ID:RiBir1w3 納得しないと進まないタイプなので
203デフォルトの名無しさん
2019/02/23(土) 21:31:22.65ID:24PtBhaW204デフォルトの名無しさん
2019/02/23(土) 21:37:05.47ID:wr+1lm8V 読んでいるサイトが悪いのではないかなあ
すごいH本とか
HaskellではなくてOcamlだけど浅井『プログラミングの基礎』とかを読んだ方が
良いレベルだと思う
すごいH本とか
HaskellではなくてOcamlだけど浅井『プログラミングの基礎』とかを読んだ方が
良いレベルだと思う
205デフォルトの名無しさん
2019/02/24(日) 01:39:36.53ID:qI0VELUi >>200
do は (>>=) の糖衣構文 (=分かりやすく見やすくするための別記法) なので最終的にはモナドと (>>=) を理解するまではしっくりこない。
https://qiita.com/saltheads/items/6025f69ba10267bbe3ee
do は (>>=) の糖衣構文 (=分かりやすく見やすくするための別記法) なので最終的にはモナドと (>>=) を理解するまではしっくりこない。
https://qiita.com/saltheads/items/6025f69ba10267bbe3ee
206デフォルトの名無しさん
2019/02/24(日) 01:52:29.83ID:BExwBIrb 最終的に>>=演算子オーバーロードを理解する頃には難易度がC++と同じ
207デフォルトの名無しさん
2019/02/24(日) 11:45:28.69ID:mBeDvEXM208デフォルトの名無しさん
2019/02/25(月) 13:11:14.94ID:EIUHHo5S haskellのGUIは何が主流なの
gtkじゃネイティブUIに見えないからqtahとか?
もしくはhaskellではGUIを扱わないとか?
gtkじゃネイティブUIに見えないからqtahとか?
もしくはhaskellではGUIを扱わないとか?
209デフォルトの名無しさん
2019/02/25(月) 21:33:28.52ID:jyEH5AtM 趣味でやってるが Threepenny 使ってる
簡単に組み合わせられるようになるかなと
Elm も学習中
簡単に組み合わせられるようになるかなと
Elm も学習中
210デフォルトの名無しさん
2019/02/26(火) 21:42:21.10ID:DUz4HSDe 書籍「Thinking with Types」の第1章をサンプルPDF版で読んでいるのですが、
19ページ目の Exercise 1.4-i でつまずいています。
数式 (a^b)^c と a^(b*c) が等しいことを Curry-Howard isomorphism を使って証明する問題ですが、
これは、
to :: (b -> c -> a) -> (b, c) -> a
from :: ((b, c) -> a) -> b -> c -> a
という型の Haskell の関数を見つけよ、と言うことですよね。
しかし、問題文に書かれている
to . from = id
from . to = id
の意味が分かりません。
to . from の型も from . to の型も共に id の型とは等しくないと思うのですが・・・
19ページ目の Exercise 1.4-i でつまずいています。
数式 (a^b)^c と a^(b*c) が等しいことを Curry-Howard isomorphism を使って証明する問題ですが、
これは、
to :: (b -> c -> a) -> (b, c) -> a
from :: ((b, c) -> a) -> b -> c -> a
という型の Haskell の関数を見つけよ、と言うことですよね。
しかし、問題文に書かれている
to . from = id
from . to = id
の意味が分かりません。
to . from の型も from . to の型も共に id の型とは等しくないと思うのですが・・・
211デフォルトの名無しさん
2019/02/26(火) 21:57:34.53ID:PosTOau2 to :: (b -> c -> a) -> ((b, c) -> a)
from :: ((b, c) -> a) -> (b -> c -> a)
from :: ((b, c) -> a) -> (b -> c -> a)
212デフォルトの名無しさん
2019/02/27(水) 01:02:26.71ID:2D6fGXPQ Haskellにはファーストクラス多相関数がないから
idの型は単相なんだろう
単相のidという名前の同音異義語がちょっと多すぎるだけ
idの型は単相なんだろう
単相のidという名前の同音異義語がちょっと多すぎるだけ
213デフォルトの名無しさん
2019/02/27(水) 02:05:02.68ID:kdg0sG7A >>209
思い出して今日発売のelm本、買おうかなと思ったら尼で売り切れててワロた。
思い出して今日発売のelm本、買おうかなと思ったら尼で売り切れててワロた。
214デフォルトの名無しさん
2019/02/28(木) 17:06:29.75ID:W9NOQ7xg 下記の2つの関数の rank について
関数 f は rank 2、関数 g は rank 3 で合ってる?
f :: a -> (forall b. b -> c)
g :: a -> (forall b. b -> c) -> d
関数 f は rank 2、関数 g は rank 3 で合ってる?
f :: a -> (forall b. b -> c)
g :: a -> (forall b. b -> c) -> d
215デフォルトの名無しさん
2019/03/03(日) 20:55:07.64ID:/obVPbHS216デフォルトの名無しさん
2019/03/03(日) 22:40:24.54ID:iXSrdfon 条件を満たす限り畳み込むfoldWhileみたいな関数がないのはなぜ?
scanとtakeWhileで出来なくもないけど無駄なリストが生成されちゃうよね
scanとtakeWhileで出来なくもないけど無駄なリストが生成されちゃうよね
217デフォルトの名無しさん
2019/03/04(月) 10:06:50.76ID:P5wfz8lO scanした後はlast.takeWhileとかだと思いますがfusionされるので作られません
218デフォルトの名無しさん
2019/03/04(月) 11:18:43.16ID:yQsTNF7X219デフォルトの名無しさん
2019/03/09(土) 09:51:28.74ID:KBqn1KqM haskell入門ほぼ読んだけどちょっと物足りなくてもうすこしhaskell勉強したい欲がある(目的は競プロとか月並みにaiとか)
なんかええ本ある? 数学の高速なライブラリとか圏論、モナドの解説あるやつで(数学は拒絶反応しない)
get programming with haskellとか並行並列とか多少気になってるけどどう?
なんかええ本ある? 数学の高速なライブラリとか圏論、モナドの解説あるやつで(数学は拒絶反応しない)
get programming with haskellとか並行並列とか多少気になってるけどどう?
220デフォルトの名無しさん
2019/03/09(土) 10:30:48.34ID:Vn/el/At 初心者を抜けた後、実践へ進みたいのなら幾つか勧められる本はある。
しかし、更なる勉強がしたいのなら、勧められる本はない。
初心者用か、初心者を抜けたばかりの者にはまだ難しい本しかない。
特に君の目的(競プロやAI)に叶う本は今のところ皆無だ。
なので、ネットを漁れ。
あと質問がやや曖昧で、何を求めているのか分からん。
数学の高速なライブラリの何を求めてる?
それを自作できる知識なのか?
活用する知識なのか?
もしくは、仕組みが知りたい具体的なライブラリでもあるのか?
圏論やモナドにしても然り。
それらの何が知りたいのか具体的に言ってみ。
しかし、更なる勉強がしたいのなら、勧められる本はない。
初心者用か、初心者を抜けたばかりの者にはまだ難しい本しかない。
特に君の目的(競プロやAI)に叶う本は今のところ皆無だ。
なので、ネットを漁れ。
あと質問がやや曖昧で、何を求めているのか分からん。
数学の高速なライブラリの何を求めてる?
それを自作できる知識なのか?
活用する知識なのか?
もしくは、仕組みが知りたい具体的なライブラリでもあるのか?
圏論やモナドにしても然り。
それらの何が知りたいのか具体的に言ってみ。
221デフォルトの名無しさん
2019/03/09(土) 11:02:47.64ID:KBqn1KqM >>220
具体的には数学書のような理論本ですね 今のところ全然数学臭さがないので(コンピュータとは乖離してるかもしれないけど)
速度に関しては、命令型の書き方でないのでどうすれば速度が出る書き方が出来るかが一番興味あります
ai,競プロはやるとしたときの足掛かりが気になりました
このみっつのどれかが掘り下げられれば幸いです。
具体的には数学書のような理論本ですね 今のところ全然数学臭さがないので(コンピュータとは乖離してるかもしれないけど)
速度に関しては、命令型の書き方でないのでどうすれば速度が出る書き方が出来るかが一番興味あります
ai,競プロはやるとしたときの足掛かりが気になりました
このみっつのどれかが掘り下げられれば幸いです。
222デフォルトの名無しさん
2019/03/09(土) 11:19:03.37ID:SKFKP+LU THUNKとかWHNFとかだろうけど
俺もここら辺の本とかあるなら読んでみたい
俺もここら辺の本とかあるなら読んでみたい
223デフォルトの名無しさん
2019/03/09(土) 11:28:44.92ID:Vn/el/At >>221
「数学書のような理論本」 悪いが意味が分からん。
具体的に「何が知りたいのか」を言ってくれ。
理論と言うのが大雑派すぎる。
速度を上げる方法を学びたいのなら、
・Haskell High Performance Programming
・関数プログラミング 珠玉のアルゴリズムデザイン
この2つが正にうってつけだが、
「Haskell入門をほぼ読んだ」段階では挫折しそう。
AI や競プロは前レスでも言ったが本は無い。
AI は reinforcement leaning や deep leaning など技術範囲を絞ったワードと
haskell を組み合わせたキーワードでネット検索。
競プロは実際の競技で提出されたソースをたくさん読んで真似しろ。
「数学書のような理論本」 悪いが意味が分からん。
具体的に「何が知りたいのか」を言ってくれ。
理論と言うのが大雑派すぎる。
速度を上げる方法を学びたいのなら、
・Haskell High Performance Programming
・関数プログラミング 珠玉のアルゴリズムデザイン
この2つが正にうってつけだが、
「Haskell入門をほぼ読んだ」段階では挫折しそう。
AI や競プロは前レスでも言ったが本は無い。
AI は reinforcement leaning や deep leaning など技術範囲を絞ったワードと
haskell を組み合わせたキーワードでネット検索。
競プロは実際の競技で提出されたソースをたくさん読んで真似しろ。
224デフォルトの名無しさん
2019/03/09(土) 11:50:40.66ID:KBqn1KqM225デフォルトの名無しさん
2019/03/09(土) 13:09:34.75ID:HqfcKPNw 競プロにHaskellはどうなんだ…?
良くわからんけどSTモナド使いまくる感じになるのかな
あるいは珠玉のアルゴリズムを理解仕切った超人達の集まりなのか
良くわからんけどSTモナド使いまくる感じになるのかな
あるいは珠玉のアルゴリズムを理解仕切った超人達の集まりなのか
226デフォルトの名無しさん
2019/03/09(土) 13:43:47.24ID:w1EXpOnc >>221,223
珠玉のアルゴリズムデザインへの入門としては同じ著者の
『Haskellによる関数プログラミングの思考法』
(旧版名は『関数プログラミング入門 ―Haskellで学ぶ原理と技法―』)
がいいと思う
他の入門書よりは数学色が強いし
等式変形によって効率を改善していく運算も割と丁寧に扱っていると思う
あとは『純粋関数型データ構造』とかも参考になるかも?
ただ競プロならSTRefとかSTUArrayとかに習熟するほうが
手っ取り早いし有力かも
珠玉のアルゴリズムデザインへの入門としては同じ著者の
『Haskellによる関数プログラミングの思考法』
(旧版名は『関数プログラミング入門 ―Haskellで学ぶ原理と技法―』)
がいいと思う
他の入門書よりは数学色が強いし
等式変形によって効率を改善していく運算も割と丁寧に扱っていると思う
あとは『純粋関数型データ構造』とかも参考になるかも?
ただ競プロならSTRefとかSTUArrayとかに習熟するほうが
手っ取り早いし有力かも
227デフォルトの名無しさん
2019/03/09(土) 13:49:45.09ID:Vn/el/At >>225 >>226
例えば AtCoder の参加者のコードを見てみると分かるが、
STモナドなんて使ってるヤツはいない。
そもそも、haskell に慣れたら、STモナドなんて使いにくいだけだろ。
競プロみたいな短く速いコードを書く必要があるなら尚更。
珠玉本を理解しきった者かどうかは知らんが、
極端に短いコードで解いてくるヤツは、
どちらかといえば数学の知識が豊富なんじゃないかな。
問題文を数学の世界に落とし込む事に長けているように見える。
コンテストにもよるが、競技プログラミングは
個人的にはアルゴリズム力よりも数学力がより大事だと思ってる。
例えば Project Euler の高番号問題をシンプルに解けるヤツは競技も強そう。
例えば AtCoder の参加者のコードを見てみると分かるが、
STモナドなんて使ってるヤツはいない。
そもそも、haskell に慣れたら、STモナドなんて使いにくいだけだろ。
競プロみたいな短く速いコードを書く必要があるなら尚更。
珠玉本を理解しきった者かどうかは知らんが、
極端に短いコードで解いてくるヤツは、
どちらかといえば数学の知識が豊富なんじゃないかな。
問題文を数学の世界に落とし込む事に長けているように見える。
コンテストにもよるが、競技プログラミングは
個人的にはアルゴリズム力よりも数学力がより大事だと思ってる。
例えば Project Euler の高番号問題をシンプルに解けるヤツは競技も強そう。
228デフォルトの名無しさん
2019/03/09(土) 15:47:05.82ID:KBqn1KqM229デフォルトの名無しさん
2019/03/09(土) 20:50:02.63ID:2ErVpr0y 珠玉本難解すぎる
登場する学生達が天才過ぎる
登場する学生達が天才過ぎる
230デフォルトの名無しさん
2019/03/10(日) 04:06:11.50ID:0rKUQSsg >>229
それでも理解したいのなら質問すればいい
それでも理解したいのなら質問すればいい
231デフォルトの名無しさん
2019/03/14(木) 01:49:52.87ID:pUnQtnNt instance head ってよく聞くけど、
これは instance 宣言のどの部分のこと?
例えば次の宣言の場合
instance (Foo a) => Bar (Baz a b) | a -> b where
・(Foo a)
・Bar (Baz a b)
・Bar (Baz a b) | a -> b
・instance キーワードと where キーワードの間の全部
・その他
どれ?
これは instance 宣言のどの部分のこと?
例えば次の宣言の場合
instance (Foo a) => Bar (Baz a b) | a -> b where
・(Foo a)
・Bar (Baz a b)
・Bar (Baz a b) | a -> b
・instance キーワードと where キーワードの間の全部
・その他
どれ?
232デフォルトの名無しさん
2019/03/14(木) 02:00:29.34ID:pUnQtnNt >>231
すまん、instance 宣言に関数従属は無いよな。
改めて、
instance (Foo a) => Bar (Baz a) where
この例だとどこが instance head なんだ?
すまん、instance 宣言に関数従属は無いよな。
改めて、
instance (Foo a) => Bar (Baz a) where
この例だとどこが instance head なんだ?
233デフォルトの名無しさん
2019/03/14(木) 08:32:21.91ID:pUnQtnNt234デフォルトの名無しさん
2019/03/20(水) 22:23:43.02ID:GM5azBbl HaskellのGUI(Gtk2hs)でカウンター作ってみた。
import Graphics.UI.Gtk
main = do
initGUI
window <- windowNew
set window [windowTitle := "counter", containerBorderWidth := 10]
mainbox <- vBoxNew True 5
containerAdd window mainbox
label <- labelNewWithMnemonic "0"
boxPackStart mainbox label PackNatural 0
countbtn <- buttonNewWithLabel "Count"
clrbtn <- buttonNewWithLabel "Clear"
boxPackStart mainbox countbtn PackNatural 0
boxPackEnd mainbox clrbtn PackNatural 0
widgetShowAll window
onClicked countbtn (labelGetLabel label >>= \n -> labelSetText label (show (1 + (read n))))
onClicked clrbtn (labelSetText label "0")
onDestroy window mainQuit
mainGUI
import Graphics.UI.Gtk
main = do
initGUI
window <- windowNew
set window [windowTitle := "counter", containerBorderWidth := 10]
mainbox <- vBoxNew True 5
containerAdd window mainbox
label <- labelNewWithMnemonic "0"
boxPackStart mainbox label PackNatural 0
countbtn <- buttonNewWithLabel "Count"
clrbtn <- buttonNewWithLabel "Clear"
boxPackStart mainbox countbtn PackNatural 0
boxPackEnd mainbox clrbtn PackNatural 0
widgetShowAll window
onClicked countbtn (labelGetLabel label >>= \n -> labelSetText label (show (1 + (read n))))
onClicked clrbtn (labelSetText label "0")
onDestroy window mainQuit
mainGUI
235デフォルトの名無しさん
2019/03/20(水) 22:24:12.70ID:GM5azBbl label <- labelNewWithMnemonic "0"
boxPackStart mainbox label PackNatural 0
countbtn <- buttonNewWithLabel "Count"
clrbtn <- buttonNewWithLabel "Clear"
boxPackStart mainbox countbtn PackNatural 0
boxPackEnd mainbox clrbtn PackNatural 0
widgetShowAll window
onClicked countbtn (labelGetLabel label >>= \n -> labelSetText label (show (1 + (read n))))
onClicked clrbtn (labelSetText label "0")
onDestroy window mainQuit
mainGUI
boxPackStart mainbox label PackNatural 0
countbtn <- buttonNewWithLabel "Count"
clrbtn <- buttonNewWithLabel "Clear"
boxPackStart mainbox countbtn PackNatural 0
boxPackEnd mainbox clrbtn PackNatural 0
widgetShowAll window
onClicked countbtn (labelGetLabel label >>= \n -> labelSetText label (show (1 + (read n))))
onClicked clrbtn (labelSetText label "0")
onDestroy window mainQuit
mainGUI
236デフォルトの名無しさん
2019/03/20(水) 22:24:33.45ID:GM5azBbl boxPackStart mainbox countbtn PackNatural 0
boxPackEnd mainbox clrbtn PackNatural 0
widgetShowAll window
onClicked countbtn (labelGetLabel label >>= \n -> labelSetText label (show (1 + (read n))))
onClicked clrbtn (labelSetText label "0")
onDestroy window mainQuit
mainGUI
boxPackEnd mainbox clrbtn PackNatural 0
widgetShowAll window
onClicked countbtn (labelGetLabel label >>= \n -> labelSetText label (show (1 + (read n))))
onClicked clrbtn (labelSetText label "0")
onDestroy window mainQuit
mainGUI
237デフォルトの名無しさん
2019/03/21(木) 05:11:02.25ID:EnD5r7yP コマンドラインでエンターを押すごとに数字が増えていく(Ctrl+C押すまで止まらない)
Haskellコード
main = mapM_ (\n -> print n >> getLine) [0..]
out:
0
1
2
3
4
Haskellコード
main = mapM_ (\n -> print n >> getLine) [0..]
out:
0
1
2
3
4
238デフォルトの名無しさん
2019/03/21(木) 22:17:24.35ID:2nCrXVEC 急にどしたんww
gtk2hsのドキュメントがHackageから消えてるのは気のせい?
gtk2hsのドキュメントがHackageから消えてるのは気のせい?
239デフォルトの名無しさん
2019/03/21(木) 22:23:19.66ID:NO+0ze73 なかなかGHC8.8出ないね
240デフォルトの名無しさん
2019/03/21(木) 23:42:33.25ID:42YMN3yF 無限ポップアップ上げるやつ現れないとは高尚なスレ
リストで遅延評価使うのがなかなかハスケルっぽい
リストで遅延評価使うのがなかなかハスケルっぽい
241デフォルトの名無しさん
2019/03/22(金) 06:11:43.80ID:t/nkQ3ne 一応、カウンターみたいなのは純粋関数型言語には作れない言われてたから、作ってみた。
確かにi++みたいな事は出来ないが、違う方法で参照透明性を確保しつつ実現出来ると実感。
(個人的にHaskellには副作用はあると考えているが、参照透明性は崩れないとも考えている)
確かにi++みたいな事は出来ないが、違う方法で参照透明性を確保しつつ実現出来ると実感。
(個人的にHaskellには副作用はあると考えているが、参照透明性は崩れないとも考えている)
242デフォルトの名無しさん
2019/03/22(金) 07:23:09.19ID:hntcvuv1 そりゃ副作用はあるよ。
じゃなきゃIO処理できない。
haskell の特徴は純粋な関数から副作用のある関数を呼べないこと。
じゃなきゃIO処理できない。
haskell の特徴は純粋な関数から副作用のある関数を呼べないこと。
243デフォルトの名無しさん
2019/03/22(金) 07:32:41.43ID:t/nkQ3ne うい。
そう言う仕組みになってるくせに、IOな関数も扱いとしては純粋な関数と同じ扱いなのが気に入ってます。
(型に気をつけていれば自然とそうなるし、普通にprint関数と純粋関数を関数合成出来るのが好き)
そう言う仕組みになってるくせに、IOな関数も扱いとしては純粋な関数と同じ扱いなのが気に入ってます。
(型に気をつけていれば自然とそうなるし、普通にprint関数と純粋関数を関数合成出来るのが好き)
244デフォルトの名無しさん
2019/03/22(金) 07:54:45.66ID:chPt0Ign 純粋関数型言語でカウンタが作れないというのは、
同じ関数を呼び出した結果がカウントアップされるような関数のこと。
pythonで書くとこんな感じ。
>>> def create_counter():
n = 0
def counter():
nonlocal n
n += 1
return n
return counter
>>> counter = create_counter()
>>> counter()
1
>>> counter()
2
同じ関数を呼び出した結果がカウントアップされるような関数のこと。
pythonで書くとこんな感じ。
>>> def create_counter():
n = 0
def counter():
nonlocal n
n += 1
return n
return counter
>>> counter = create_counter()
>>> counter()
1
>>> counter()
2
245デフォルトの名無しさん
2019/03/22(金) 08:09:16.10ID:t/nkQ3ne >>244
そうなんですが、純粋関数型言語の場合、その関数を何回呼び出したのかカウントする関数を作るみたいな視点の切り替えで対処するのではと。
つまり自身のファイルを読み込んで自身(counter関数)を
a = counter
b = counter
a = 1
b = 2
に置き換える関数なら作れます。
欲しいのは結果であり、動作ではなく結果が同じなら良いと言う解釈です。
そうなんですが、純粋関数型言語の場合、その関数を何回呼び出したのかカウントする関数を作るみたいな視点の切り替えで対処するのではと。
つまり自身のファイルを読み込んで自身(counter関数)を
a = counter
b = counter
a = 1
b = 2
に置き換える関数なら作れます。
欲しいのは結果であり、動作ではなく結果が同じなら良いと言う解釈です。
246デフォルトの名無しさん
2019/03/22(金) 10:06:06.24ID:t/nkQ3ne 終了やカウントクリアに対応してみた。
import System.Exit
main = do putStrLn "quit code is 'q', count clear code 'c'"
mapM_ (\n -> print n >> getLine >>= f) [0..]
f "quit" = exitWith ExitSuccess
f "clear" = main
f _ = return ()
import System.Exit
main = do putStrLn "quit code is 'q', count clear code 'c'"
mapM_ (\n -> print n >> getLine >>= f) [0..]
f "quit" = exitWith ExitSuccess
f "clear" = main
f _ = return ()
247デフォルトの名無しさん
2019/03/22(金) 11:13:34.22ID:RqYJx/o4 副作用もカウンタもGUIもHaskellでできる (Haskellで作れるとは言っていない)
248デフォルトの名無しさん
2019/03/22(金) 14:11:11.50ID:t/nkQ3ne まあ要はcounter関数はswap関数と同じですよ。
手続き型言語ではソートや繰り返しに必須ですが、関数型言語で各種ソート作る時にswap関数は使った事がない。
木を見て森を見ずというか、counter関数を何に使うの?って話で、カウンターとしての用途なら再帰関数の引数でf (x + 1)とか渡せば良いだけですし。
loop10 n | n > 10 = return ()
loop10 n = print n >> getLine >> loop10 (n + 1)
手続き型言語ではソートや繰り返しに必須ですが、関数型言語で各種ソート作る時にswap関数は使った事がない。
木を見て森を見ずというか、counter関数を何に使うの?って話で、カウンターとしての用途なら再帰関数の引数でf (x + 1)とか渡せば良いだけですし。
loop10 n | n > 10 = return ()
loop10 n = print n >> getLine >> loop10 (n + 1)
249デフォルトの名無しさん
2019/03/22(金) 14:35:43.76ID:tc5CuCjg つまりHaskell(というかElm?)で無限アラート書いとけば捕まらなかった?
250デフォルトの名無しさん
2019/03/22(金) 15:17:19.58ID:JJ/MZDcL Haskellの再帰は場合によってはヒープを使うから
10^9回ぐらい閉じる奴がいたらサイバーテロとして扱われてたかもしれない
10^9回ぐらい閉じる奴がいたらサイバーテロとして扱われてたかもしれない
251デフォルトの名無しさん
2019/03/22(金) 15:36:25.55ID:t/nkQ3ne そこは気を付けなきゃだけど(と言うか、スタックは兎も角ヒープ使うってreverseみたいにリスト溜め込むとかだけで、手続き型言語でもあり得る場面に限られそうだが)、
むしろモナドな再帰(IOはもちろん、リスト->リストな再帰も)がループになると言うのは、
手続き型言語よりも再帰でスタック使うケースが少ないと言う魅力もある。
(ここは手続き型言語が末尾再帰最適化に対応しても追いつけない所)
>>246 の通り、mainを再帰的に呼び出してもループになると言うのは知る限り手続き型言語では見たことない。
main変数が他の言語で言うmain関数的な動きをしているのも、圏論的には変数は引数無しの関数と見做せるから。
main変数を評価しようとすると束縛されたプログラムが動き出す。
n = 1 ― 変数であり、常に1を返す引数無しの関数
むしろモナドな再帰(IOはもちろん、リスト->リストな再帰も)がループになると言うのは、
手続き型言語よりも再帰でスタック使うケースが少ないと言う魅力もある。
(ここは手続き型言語が末尾再帰最適化に対応しても追いつけない所)
>>246 の通り、mainを再帰的に呼び出してもループになると言うのは知る限り手続き型言語では見たことない。
main変数が他の言語で言うmain関数的な動きをしているのも、圏論的には変数は引数無しの関数と見做せるから。
main変数を評価しようとすると束縛されたプログラムが動き出す。
n = 1 ― 変数であり、常に1を返す引数無しの関数
252デフォルトの名無しさん
2019/03/22(金) 17:16:42.19ID:JJ/MZDcL いやGHCが与えるスタックはヒープなんだよ
Cのコールスタックみたいな固定領域じゃなくてね
それもデフォルトで最大メモリの8割というデカさだから
うっかり非末尾再帰を放っておこうものならスワップ地獄に陥る
Cのコールスタックみたいな固定領域じゃなくてね
それもデフォルトで最大メモリの8割というデカさだから
うっかり非末尾再帰を放っておこうものならスワップ地獄に陥る
253デフォルトの名無しさん
2019/03/22(金) 18:49:40.42ID:tc5CuCjg 非末尾再帰を末尾再帰に自動変換するのって技術的に不可能?
末尾再帰ってなんか無理やり感あるよね
末尾再帰ってなんか無理やり感あるよね
254デフォルトの名無しさん
2019/03/22(金) 19:00:24.32ID:E/4CSIEY フィボナッチを再帰で書くと定義がそのまま動く感動が味わえるのに末尾再帰に書き直すととたんに台無しになるよねw
255デフォルトの名無しさん
2019/03/22(金) 22:26:05.94ID:t/nkQ3ne ヒープにあろうがスタックにあろうが末尾再帰に意識して書けばまず解決する問題だね。
ghciやrunghcみたいなスクリプト形式だと最適化(部分的な正格評価)が不十分で
sum’ n [] = n
sum’ n (x:xs) = sum’ (n + x) xs
という末尾再帰があった場合、
sum’ 0 [1,2,3]
= sum’ (0 + 1) [2,3]
= sum’ ((0 + 1)+ 2) [3]
= sum’ (((0 + 1)+ 2)+ 3) []
みたいに(遅延評価のせいで)結果を入れる変数の方でスタック消費するけども、コンパイラ(ghc)の方はこの問題は無い。
ghciやrunghcみたいなスクリプト形式だと最適化(部分的な正格評価)が不十分で
sum’ n [] = n
sum’ n (x:xs) = sum’ (n + x) xs
という末尾再帰があった場合、
sum’ 0 [1,2,3]
= sum’ (0 + 1) [2,3]
= sum’ ((0 + 1)+ 2) [3]
= sum’ (((0 + 1)+ 2)+ 3) []
みたいに(遅延評価のせいで)結果を入れる変数の方でスタック消費するけども、コンパイラ(ghc)の方はこの問題は無い。
256デフォルトの名無しさん
2019/03/22(金) 22:43:20.21ID:t/nkQ3ne >>254
別に数列(リスト)から取り出す形にすれば末尾再帰にする必要ないでしょ。
main = print $ fibs!!3 ― 0から数えて3番目
where fibs = 0:1:zipWith (+) fibs (tail fibs)
foldlの正格評価版 foldl’みたいにzipWithの正格評価版作って差し替えると高速化する。
(このネタ書いてたブログの人はzipWith’を標準で入れてて欲しいって書いてた)
zipWith’ f (x:xs) (y:ys) = seq a $ a:zipWith f xs ys
where a = f x y
zipWith’ _ _ _ = []
別に数列(リスト)から取り出す形にすれば末尾再帰にする必要ないでしょ。
main = print $ fibs!!3 ― 0から数えて3番目
where fibs = 0:1:zipWith (+) fibs (tail fibs)
foldlの正格評価版 foldl’みたいにzipWithの正格評価版作って差し替えると高速化する。
(このネタ書いてたブログの人はzipWith’を標準で入れてて欲しいって書いてた)
zipWith’ f (x:xs) (y:ys) = seq a $ a:zipWith f xs ys
where a = f x y
zipWith’ _ _ _ = []
257デフォルトの名無しさん
2019/03/22(金) 23:37:15.19ID:cqN2FVLj >>256
定義そのままで書きたいって話であって末尾再帰だからダメとは言ってないでござるよ
定義そのままで書きたいって話であって末尾再帰だからダメとは言ってないでござるよ
258デフォルトの名無しさん
2019/03/23(土) 11:46:10.06ID:CUvnstPX 「感動」はダメとは言わないが意味がわからないと言いたい
259デフォルトの名無しさん
2019/03/23(土) 11:57:03.27ID:XiFmcVOc 自然に書くなら数学の定義通り書くよね
でも今のコンピュータの制約上仕方なく末尾再帰にしないといけないよね
自然に書ける日は来ないのかなあってある種当たり前の感覚だと思うけど
でも今のコンピュータの制約上仕方なく末尾再帰にしないといけないよね
自然に書ける日は来ないのかなあってある種当たり前の感覚だと思うけど
260デフォルトの名無しさん
2019/03/23(土) 11:59:26.53ID:OxD1K8Qf コンピューターの制約で変えねばならないならば定義に問題がある
定義は可能な限り一般に適用可能でなければならない
よって定義を変えればよい
定義は可能な限り一般に適用可能でなければならない
よって定義を変えればよい
261デフォルトの名無しさん
2019/03/23(土) 12:03:29.66ID:CUvnstPX 感情をそのまま言語化できるなら犬や猫も言葉を話せることになる
実際には感情と言語は一致しないので感情をそのまま言語化することはない
実際には感情と言語は一致しないので感情をそのまま言語化することはない
262デフォルトの名無しさん
2019/03/23(土) 12:16:16.80ID:XiFmcVOc 何か噛み合ってないな
自然な感覚に近い表現ができるほうが可読性高いよねくらいの話でしかないはずなのに
今何の話になってるんだ??
自然な感覚に近い表現ができるほうが可読性高いよねくらいの話でしかないはずなのに
今何の話になってるんだ??
263デフォルトの名無しさん
2019/03/23(土) 12:18:39.39ID:CUvnstPX 言葉を話さない動物やAIには言語の制約がない
ゆえに動物やAIは人間を超える可能性がある
壮大な詭弁だ
ゆえに動物やAIは人間を超える可能性がある
壮大な詭弁だ
264デフォルトの名無しさん
2019/03/23(土) 12:22:19.42ID:OxD1K8Qf 末尾再帰=ループ
分岐が発生するとこの関係が崩れる
分岐が発生するとこの関係が崩れる
265デフォルトの名無しさん
2019/03/23(土) 12:26:33.46ID:XiFmcVOc 何か変なとこに手出しちゃったみたいですね
もうやめときます
スレ汚し失礼しました
もうやめときます
スレ汚し失礼しました
266デフォルトの名無しさん
2019/03/23(土) 13:28:21.51ID:CUvnstPX 可読性で思い出したが
ソースを読まなくても使ってみればわかることは読まない方がいい
読んだときの自然な感覚なんかよりも、そもそも読まないのが最も自然
ソースを読まなくても使ってみればわかることは読まない方がいい
読んだときの自然な感覚なんかよりも、そもそも読まないのが最も自然
267デフォルトの名無しさん
2019/03/23(土) 16:34:59.79ID:3o0No0Hu 可読性をあげるためだけに型に別名つけるのってどうなの
type Description = Text
みたいなやつ
type Description = Text
みたいなやつ
268デフォルトの名無しさん
2019/03/23(土) 17:38:52.05ID:LmX3enfk まあ読みやすさっていうか書きやすさだよなそれ
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 高市首相答弁を“引き出した”立民・岡田克也氏が改めて説明「なぜ慎重な答弁をされなかったのか。非常に残念に思っている」 ★9 [ぐれ★]
- 【news23】小川彩佳アナ「ここまでの広がりになるということを、高市総理はどれだけ想像できていたんでしょうね」 日中問題特集で [冬月記者★]
- 【独占スクープ】元TOKIOの松岡昌宏がSTARTO社を“退所”へ「国分のコンプライアンス違反」問題をきっかけに決断、12月から単独で活動 [Ailuropoda melanoleuca★]
- 【野球】大谷翔平、佐々木朗希、山本由伸らがWBC辞退なら広がる不協和音… 『過去イチ盛り上がらない大会』になる可能性も★2 [冬月記者★]
- 「町中華」の“息切れ倒産”が増加 ブームにも支えられ職人技で踏ん張ってきたが… 大手チェーンは値上げでも絶好調 [ぐれ★]
- 【国際】ロシアはすでに戦争準備段階――ポーランド軍トップが警告 ★2 [ぐれ★]
- 高市早苗、約1ヶ月でドル円・10円円安を達成 [256556981]
- 26歳で母親46歳だけど45とかで子供産む人正直グロいな…
- するってぇと何かい?2週間前に安全を確認して輸入再開した海産物を食の安全のために輸入停止にしたってのかい?
- 【高市核兵器】 小泉コメ防衛大臣「民主党政権 岡田外務大臣の “非核三原則” に関する国会答弁を引き継いでいる」 政策堅持を明言 [485983549]
- 【超絶朗報】高市早苗、月給5万円アップを突如確定させるWWWWW
- 【高市賃上げ】 自民党&維新の会「国会議員の給与を 月5万円アップさせる!」 今国会で歳費法改正。 月129万円→月134万円に [485983549]
