[過去ログ] 関数型プログラミング言語Haskell Part32 (1002レス)
上下前次1-新
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
9(11): デフォルトの名無しさん [sage] 2019/02/03(日) 12:58:27.43 ID:5bolWXfM(1/36) AAS
haskell紹介してるブログとか色々あるけどどこも肝心要のところがすっぽり抜けててイライラするな・・
例えば
fact 0 = 1
fact n = n * fact(n - 1)
これ無限ループになっちゃって終わらないでしょ終端条件も書いてないし。
fact 3を展開すると
3 * ( 2 * ( 1 * ( 1 * ………
0を入力すれば1になるってことはこの先ずーっと1が繰り返されるだけだし。
同じ値が2度続いたら処理を止めるとか変な仕組みでも入ってるのかねー
13(3): デフォルトの名無しさん [sage] 2019/02/03(日) 20:51:10.38 ID:5bolWXfM(2/36) AAS
>>12それじゃ納得できないんだけども
終わるから大丈夫仕様ですってもやっとするから
>>9で書いたように1が無限に続いちゃうと思うんだけどな
0が入力されたら1を返すってことだから
1 - 1でまた繰り返しちゃうよね
そもそもどの値が来たら終わるか全く記述がないよね
そういうところも納得できないっていうかおかしい
15(3): デフォルトの名無しさん [sage] 2019/02/03(日) 21:13:08.06 ID:5bolWXfM(3/36) AAS
>>14あの説明で納得するようならここ来てないから
あれだとブログの説明と何も変わらない
まさか1かtrueを返したら問答無用で終わる仕様だったりするのかねー
18(1): デフォルトの名無しさん [sage] 2019/02/03(日) 21:19:06.57 ID:5bolWXfM(4/36) AAS
>>1616(1): デフォルトの名無しさん [sage] 2019/02/03(日) 21:15:44.35 ID:DVkCUlxV(2/11) AAS
>>13
ああ 言っている意味は分かったけど
続かねーぞ よく考えてみ 恥ずかしい思いするだろうけど
っていうか、>>11のひとが書いてるじゃん
fact 1 = 1 * fact 0
= 1 * 1 で終了だろ
これ納得できないとしたら、別のところで引っかかっている
パターンマッチを理解していないとか
それじゃ終わらない
終了条件が書いていないから
なんどもいうように * 1がずーっと続くようにしか見えない
だからこの例題見たときにイライラしてたんだよね
前提となってる仕様があるけど説明省いたとかそれ系かなと
23(4): デフォルトの名無しさん [sage] 2019/02/03(日) 21:25:18.35 ID:5bolWXfM(5/36) AAS
>>1919(2): ◆QZaw55cn4c [sage] 2019/02/03(日) 21:19:41.63 ID:t4xt++Qj(2/20) AAS
>>13
では逆に質問しましょうか、そこから両者が部分的にでも合意できるポイントを探ることにしましょう
>>9
>fact 0 = 1
>fact n = n * fact(n - 1)
これをあなたはどのように解釈したかを、もう少し詳しめに記述していただくことは可能でしょうか、私の記述は今は >>13 が精一杯ですが、あなたの返答をみて改善できる点はないか検討したいと思います
理解したのは>>9の通りで
仮定として1かtrueを返したら再帰は止まる仕様になってると推測してる
>>2020(2): デフォルトの名無しさん [sage] 2019/02/03(日) 21:20:07.09 ID:RwDwNYzW(2/27) AAS
>>15
ほとんど同じ説明だが…
関数の定義が
fact 0 = 1
fact n = n * fact(n - 1)
となっている。
このとき、左辺が右辺に置き換えられる (簡約という)
つまり fact 3 は 3 * fact 2 に置き換えられる
そして fact 2 は 2 * fact 1 に置き換えられる
そして fact 1 は 1 * fact 0 に置き換えられる
ひとつめの関数の定義により、fact 0 は 1 に置き換えられるので
置き換えはここでとまる
以上をまとめると
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0
= 3 * 2 * 1 * 1
= 6
だからfact(1)で無限に続いちゃうよね
1 - 1で fact 0をevalしてまたfact(1)になる
そこで終了条件が必要だけど何にも書いてないから記述通りならずーっと続く
としか見えないんだよね
25(3): デフォルトの名無しさん [sage] 2019/02/03(日) 21:27:00.44 ID:5bolWXfM(6/36) AAS
>>2222(1): ◆QZaw55cn4c [sage] 2019/02/03(日) 21:22:54.49 ID:t4xt++Qj(3/20) AAS
>>18
終了条件は
>fact 0 = 1
です。関数 fact の引数が 0 なら、1 を関数の値として返し、fact の求値作業は終了します。
fact への入力が 1 でないならば
>fact n = n * fact(n - 1)
の定義をつかって、最初の入力 n よりも小さい値 n - 1 (< n) を使った関数定義がつかえるように変換します
ということはやっぱり1を返したら必ず再帰は止まる仕様であってるのかな?
だったらすっきりするんだけども
33(4): デフォルトの名無しさん [sage] 2019/02/03(日) 21:33:05.02 ID:5bolWXfM(7/36) AAS
>>2828(1): デフォルトの名無しさん [sage] 2019/02/03(日) 21:29:11.55 ID:RwDwNYzW(3/27) AAS
>>23
>>>20
>だからfact(1)で無限に続いちゃうよね
>1 - 1で fact 0をevalしてまたfact(1)になる
>そこで終了条件が必要だけど何にも書いてないから記述通りならずーっと続く
そうはならない
fact 1 = 1 * fact 0
に簡約される
そして
fact 0 = 1 であって
fact 0 = 0 * fact(0 - 1) とは絶対にならないからここで終わる
高校数学がわかるなら、漸化式と同じだと思えばよい
いやいやfact(1)の評価は0なんだし
fact 0の定義があるからまた1
どう考えても続くんだよね
そもそも再起から脱出するためのコードがどこにもないから怪しいとも踏んでる
何か前提となってる仕様がありそうだ
34(1): デフォルトの名無しさん [sage] 2019/02/03(日) 21:34:47.28 ID:5bolWXfM(8/36) AAS
>>29やっぱりそうなんだ
そういう重要なことは早めに説明書きしといてくれないと大混乱だわ
まースッキリしたありがと
そういう仕様なら色々めんどくさいな・・・
42(4): デフォルトの名無しさん [sage] 2019/02/03(日) 21:39:35.29 ID:5bolWXfM(9/36) AAS
>>35教えてもらったからもう大丈夫だよ
1で再起が止まる仕様なら納得だし
>>3636(1): ◆QZaw55cn4c [sage] 2019/02/03(日) 21:35:45.64 ID:t4xt++Qj(6/20) AAS
>>33
>いやいやfact(1)の評価は0なんだし
ここが違っています。
fact(1) の評価は 1 * fact(0) であって、 0 じゃないです
fact(0) の値が具体的になにかは、fact(0) を意識しはじめた時点では分からないのですよ
fact(1)を入力したら 1-1を評価するから fact 0
特に問題ないよ
1で止まる仕様らしいからそれを前提にコード考えないといかんのか・・
ややこしいことになるねこれ
44(2): デフォルトの名無しさん [sage] 2019/02/03(日) 21:41:42.22 ID:5bolWXfM(10/36) AAS
>>39どーゆーこと
もうそれで覚えちゃったんだけども・・
50(2): デフォルトの名無しさん [sage] 2019/02/03(日) 21:46:48.03 ID:5bolWXfM(11/36) AAS
>>45それだと>>9の通りで揺らがない
>>4646(1): ◆QZaw55cn4c [sage] 2019/02/03(日) 21:43:22.74 ID:t4xt++Qj(7/20) AAS
>>42
>1で再起が止まる仕様なら納得だし
理解が不十分じゃないかと危惧します、その台詞「1 で再起がとまる」という言葉ですが、「何が」 1 で再起が止まる、と考えているのですか?
あなたの発言は、いちいち「何が」「どうだ」の「何が」が欠けているので不安です
この記述だと無限に *1が続くわけだから
なにか終了条件が必要なわけで
1を返したら再帰が止まる仕様ならなるほど納得
53(1): デフォルトの名無しさん [sage] 2019/02/03(日) 21:49:54.21 ID:5bolWXfM(12/36) AAS
>>48大混乱してきた
1で再帰は必ず止まるんでないならさらにわからなくなるんだけども
55: デフォルトの名無しさん [sage] 2019/02/03(日) 21:51:42.20 ID:5bolWXfM(13/36) AAS
>>5151(2): ◆QZaw55cn4c [sage] 2019/02/03(日) 21:47:09.11 ID:t4xt++Qj(9/20) AAS
>>42
>fact(1)を入力したら 1-1を評価する
どうしてそう考えたのですか?そのような記述がどこに書かれていたのか説明いただけませんか?
fact(1)はfact(n-1)によってfact(0)になるよね
実は式自体が予想外の評価するってことなのかな?
いやまさかね・・
60(4): デフォルトの名無しさん [sage] 2019/02/03(日) 21:57:58.25 ID:5bolWXfM(14/36) AAS
>>5656(1): ◆QZaw55cn4c [sage] 2019/02/03(日) 21:52:52.90 ID:t4xt++Qj(10/20) AAS
>>50
>この記述だと無限に *1が続くわけだから
あなたの理解になにが足りないのかがわかるような気がしてきました。
「fact の引数が 1 である」と「fact の求値が 1 である」とを区別していないようですね
この二つは厳然として異なります
fact 0 = 1
は、fact(0) の「求値が」1 である、といっているのです
fact n = n * fact (n - 1)
は、たとえば
fact 8 = 8 * fact 7
fact 7 = 7 * fact 6
fact 6 = 6 * fact 5
fact 5 = 5 * fact 4
fact 4 = 4 * fact 3
fact 3 = 3 * fact 2
fact 2 = 2 * fact 1
という記述を纏めて表現しているのであり、これは fact n の「求値」は fact (n - 1) という、もともとの引数 n とは違う n - 1 という引数を使った fact の求値で定義しているのです
ごめん意味不明わからん
>>5757(3): デフォルトの名無しさん [sage] 2019/02/03(日) 21:53:28.07 ID:RwDwNYzW(11/27) AAS
もしかすると、だけど
fact 0 = 1
を実行した直後に
fact 1 = 1 * fact 0
が続くと考えている?
もうしそうだとしたらそこが間違いで
fact 0 = 1
fact n = n * fact(n - 1)
はそのどちらかしか実行されない
もちろんそのように考えてる
fact 0 = 1の結果はすぐ反映されるんじゃないの?
64(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:02:19.10 ID:5bolWXfM(15/36) AAS
>>6363(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:00:18.19 ID:RwDwNYzW(12/27) AAS
>>60
ああ、良かった
>fact 0 = 1の結果はすぐ反映されるんじゃないの?
そうだよ。そして fact 0 は 1 を返すから、もう再帰呼出しは起こらないよね?
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0
= 3 * 2 * 1 * 1
= 6
いやいや終了条件が何も書かれてないから結局は続くよ
どのみちfact 0が1となるならまたfact(1-1)でfact(0)でしょ
間違ってないはずなんだけど何か使ってる人には常識的なお約束事とかあるのかな
66(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:06:24.90 ID:5bolWXfM(16/36) AAS
>>6565(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:02:55.82 ID:DVkCUlxV(8/11) AAS
>>60
>fact 0 = 1の結果はすぐ反映されるんじゃないの?
ようするにそこでとまる
数学の階乗だから fact nの引数は再帰する度に-1される。
どこかで、factの引数が0になったら、それ以上は再帰しない
難しい話じゃないし、他の言語で再帰理解していたら、分かるはず
自分で落ち着いて考えてごらん
いやただのカウンターだったとしても止まらないし
やっぱりおかしいとは思う
何か前提がありそうな気はする
70(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:10:11.03 ID:5bolWXfM(17/36) AAS
>>6767(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:07:56.45 ID:DdA3Wm74(3/9) AAS
>>64
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0 -- fact 0が・・
= 3 * 2 * 1 * 1 -- 1になる。factもうないのにここから何が続くの?
= 6
= 3 * 2 * 1 * 1
= 3 * 2 * 1 * 1 * fact( 1 - 1 )
= 3 * 2 * 1 * 1 * 1 * fact ( 1 - 1)
どこまでも続くじゃない・・
73(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:14:19.16 ID:5bolWXfM(18/36) AAS
>>6969(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:08:36.79 ID:DVkCUlxV(9/11) AAS
>>66
だとすると文法自体理解していない あるいは関数自体
もっと、詳しく書くと
>どのみちfact 0が1となるならまたfact(1-1)でfact(0)でしょ
定義を見てごらん
fact 0 = 1 でこれは、=の右にfactが無いからこれで再帰はしないで、ここで終了
fact n = n * fact n-1 で=の右にfactがあるから再帰する
fact 0 = 1で終了するというのが納得いってない
もしそうであれば1を返せば再帰は終了すると仮定したんだ
そもそもfact 0 = 1ってマクロ定義みたいなもんだし
直ちに評価されて式に代入されるよね
75(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:18:13.63 ID:5bolWXfM(19/36) AAS
>>7272(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:13:50.28 ID:DdA3Wm74(5/9) AAS
>>70
中学校の数学でそうはならないってことは習うから、学校の数学でそこまで勉強してからプログラミングに手を出しても遅くないのでは?
プログラミング言語は数学じゃないから
再帰から脱出するならそのためのコードは絶対必要なはずなんだ
それがないってことは仕掛けがあるはずで
その仮定が1を返せば再帰から脱出できるという考え
でも違うらしいから大混乱してる
77: デフォルトの名無しさん [sage] 2019/02/03(日) 22:21:37.72 ID:5bolWXfM(20/36) AAS
>>7474(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:17:47.65 ID:DVkCUlxV(10/11) AAS
>>73
他の言語で再帰ってのは理解しているの?
fact 0 = 1で=の右にfactが無いから、再帰は終了 だから、終了条件は書かれている。
もしこれが理解できないのなら、関数定義とか、パターンマッチとかもっと基本的なことに
戻らないと理解できないと思う
Cで再帰させるなら終了条件にヒットしたらフラグたててreturnで戻ってく
関数定義の仕方ならサッと見たけど特に疑問はなかったよ
パターンマッチっていってもマクロ定義みたいなもんだし特にどうということも
79(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:24:44.77 ID:5bolWXfM(21/36) AAS
>>7676(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:19:53.64 ID:RwDwNYzW(14/27) AAS
>>73
fact 0 = 1
で「終了する」というのが間違い
fact 0 = 1
では、fact 0 が 1を返す(正確に言うと1に簡約する)
ということしか定義していない
ただ、もうfact関数を呼び出していないので、再帰呼出しはここで止まる
そして fact 0 = 1 がマクロ定義ということも勘違いなので忘れよう
>>67 が解説してくれた
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0 -- fact 0が・・
= 3 * 2 * 1 * 1 -- 1になる。factもうないのにここから何が続くの?
= 6
いやだから・・
fact 0は1なんだからその次はfact(1)になるでしょ
何も間違ってないと思うんだけど。
81(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:26:23.52 ID:5bolWXfM(22/36) AAS
>>7878(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:22:31.24 ID:RwDwNYzW(15/27) AAS
>>75
上に書いたけど、漸化式は理解している?
同じ書き方をします
Haskellは数学を基盤としているので、数学的な記述方法でプログラムが書けます
「再帰から脱出するならそのためのコードは絶対必要なはずなんだ」とあるけど、
もう書かれているよ
fact 0 = 1 って
それは終了条件じゃないよね
何が正解なのかさらに混乱して来た
86(2): デフォルトの名無しさん [sage] 2019/02/03(日) 22:30:37.00 ID:5bolWXfM(23/36) AAS
>>83だから・・
fact 0は1なんだから続くじゃない?
延々と再帰するようにしか見えない
88: デフォルトの名無しさん [sage] 2019/02/03(日) 22:32:38.86 ID:5bolWXfM(24/36) AAS
>>85PythonやJavaは知らないのでなんとも
92(5): デフォルトの名無しさん [sage] 2019/02/03(日) 22:37:00.44 ID:5bolWXfM(25/36) AAS
>>9090(1): デフォルトの名無しさん [sage] 2019/02/03(日) 22:34:03.06 ID:DdA3Wm74(8/9) AAS
>>86
fact 0は1なんだから、
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0 -- fact 0が・・
= 3 * 2 * 1 * 1 -- 1になる。factもうないのにここから何が続くの?
= 6
はい!ここで一旦休憩!君に問題。
3 * 2 * 1 * 1はいくつだ?
だから
=3 * 2 * 1 * 1 * fact(1-1)
=3 * 2 * 1 * 1 * 1*fact(1-1)
=3 * 2 * 1 * 1 * 1*1*fact(1-1)
という具合にいつまでもfactは続くよ
だから色々納得いかないことあるんだけど
上下前次1-新書関写板覧索設栞歴
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.062s