関数型プログラミング言語Haskell Part32at TECH
関数型プログラミング言語Haskell Part32 - 暇つぶし2ch1:デフォルトの名無しさん
19/01/29 09:05:47.90 gJP/u7IJ.net
関数型プログラミング言語 Haskell について語るスレです。
haskell.org (公式サイト)
URLリンク(www.haskell.org)
日本Haskellユーザーグループ
URLリンク(haskell.jp)
前スレ
関数型プログラミング言語Haskell Part31
スレリンク(tech板)

2:デフォルトの名無しさん
19/01/29 09:06:37.34 gJP/u7IJ.net
過去スレ一覧
30) スレリンク(tech板)
29) スレリンク(tech板)
28) スレリンク(tech板)
27) スレリンク(tech板)
26) スレリンク(tech板)
25) スレリンク(tech板)
24) スレリンク(tech板)
23) スレリンク(tech板)
22) スレリンク(tech板)
21) スレリンク(tech板)
20) スレリンク(tech板)
19) スレリンク(tech板)
18) スレリンク(tech板)
17) スレリンク(tech板)
16) スレリンク(tech板)
15) スレリンク(tech板)
14) スレリンク(tech板)
13) スレリンク(tech板)
12) スレリンク(tech板)
11) スレリンク(tech板)
10) スレリンク(tech板)
09) スレリンク(tech板)
08) スレリンク(tech板)
07) スレリンク(tech板)
06) スレリンク(tech板)
05) スレリンク(tech板)
04) スレリンク(tech板)
03) スレリンク(tech板)
02) スレリンク(tech板)
01) URLリンク(pc.2ch.net)

3:デフォルトの名無しさん
19/01/29 09:07:46.66 gJP/u7IJ.net
関連サイト
(英語)
Haskell - Wikibooks, open books for an open world (ページ内に内容をまとめたPDFあり)
URLリンク(en.wikibooks.org)
Learn You a Haskell for Great Good! (『すごいHaskellたのしく学ぼう!』の無料オンライン版)
URLリンク(learnyouahaskell.com)
Real World Haskell (同名書籍の無料オンライン版)
URLリンク(book.realworldhaskell.org)
(以下、日本語)
Haskell入門 5ステップ - HaskellWiki (公式サイト内、日本語入門セクション)
URLリンク(wiki.haskell.org)
Haskell - Wikibooks (上記Wikibooksの同タイトル日本語版。多くの項目が未編集)
URLリンク(ja.wikibooks.org)
Programming in Haskell
URLリンク(www.sampou.org)
Haskell のお勉強
URLリンク(www.shido.info)
Haskell Programming
URLリンク(www.geocities.jp)
本物のプログラマはHaskellを使う:ITpro
URLリンク(itpro.nikkeibp.co.jp)
[入門]関数プログラミング―質の高いコードをすばやく直感的に書ける!
URLリンク(gihyo.jp)

4:デフォルトの名無しさん
19/01/31 07:01:01.92 .net
手続き型でゴリゴリやってきた人にとって関数型は
マラソンの選手に、匍匐前進と水泳で近道するよう強制しているかのようです

5:デフォルトの名無しさん
19/01/31 07:24:27.44 4JULsXj7.net
>>4
手前味噌ですが、Haskell入門以前と言う電子書籍をAmazonでご購入下さい。
まさに貴方のような方に関数脳を作ってもらうための本です^^

6:デフォルトの名無しさん
19/01/31 20:10:32.50 KXLDvKfy.net
IOモナドは手続きモナド

7:デフォルトの名無しさん
19/02/01 07:26:12.68 L0GRy80q.net
初心者がHaskellでオンライン問題集みたいなの解いてんだけど
Haskellでやるとこういうの楽しくてええな

8:デフォルトの名無しさん
19/02/02 00:12:37.55 .net
CPS書き換えドリル
次の英文を○○構文を用いて同じ意味の英文に書き換えなさい的な

9:デフォルトの名無しさん
19/02/03 12:58:27.43 5bolWXfM.net
haskell紹介してるブログとか色々あるけどどこも肝心要のところがすっぽり抜けててイライラするな・・
例えば
fact 0 = 1
fact n = n * fact(n - 1)
これ無限ループになっちゃって終わらないでしょ終端条件も書いてないし。
fact 3を展開すると
3 * ( 2 * ( 1 * ( 1 * ………
0を入力すれば1になるってことはこの先ずーっと1が繰り返されるだけだし。
同じ値が2度続いたら処理を止めるとか変な仕組みでも入ってるのかねー

10:デフォルトの名無しさん
19/02/03 14:29:08.38 0VpSvizO.net
>>9
自分で動かしてみればわかるけど
ちゃんと終わるよ
URLリンク(wandbox.org)

11:
19/02/03 15:04:51.94 t4xt++Qj.net
>>9
>無限ループになっちゃって終わらないでしょ終端条件も書いてないし。
いえいえ、終端条件が
>fact 0 = 1
です、n ∈ N たる n からはじまって 0 で終わる、と読みます
fact 3 = 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0
= 3 * 2 * 1 * 1
で止まります.

12:デフォルトの名無しさん
19/02/03 15:10:17.81 DVkCUlxV.net
>>9
恥ずかしいぞ
>fact 0 = 1
で、これ以上再帰してないじゃん

13:デフォルトの名無しさん
19/02/03 20:51:10.38 5bolWXfM.net
>>12
それじゃ納得できないんだけども
終わるから大丈夫仕様ですってもやっとするから
>>9で書いたように1が無限に続いちゃうと思うんだけどな
0が入力されたら1を返すってことだから
1 - 1でまた繰り返しちゃうよね
そもそもどの値が来たら終わるか全く記述がないよね
そういうところも納得できないっていうかおかしい

14:デフォルトの名無しさん
19/02/03 21:08:06.34 RwDwNYzW.net
>>13
>>11 が説明してくれたとおりなのだけど、納得できない?

15:デフォルトの名無しさん
19/02/03 21:13:08.06 5bolWXfM.net
>>14
あの説明で納得するようならここ来てないから
あれだとブログの説明と何も変わらない
まさか1かtrueを返したら問答無用で終わる仕様だったりするのかねー

16:デフォルトの名無しさん
19/02/03 21:15:44.35 DVkCUlxV.net
>>13
ああ 言っている意味は分かったけど
続かねーぞ よく考えてみ 恥ずかしい思いするだろうけど
っていうか、>>11のひとが書いてるじゃん 
fact 1 = 1 * fact 0
= 1 * 1 で終了だろ

これ納得できないとしたら、別のところで引っかかっている
パターンマッチを理解していないとか

17:デフォルトの名無しさん
19/02/03 21:18:28.59 DdA3Wm74.net
>>15
バカで思い込みが激しいって最悪だぞ?どっちかにしろ。

18:デフォルトの名無しさん
19/02/03 21:19:06.57 5bolWXfM.net
>>16
それじゃ終わらない
終了条件が書いていないから
なんどもいうように * 1がずーっと続くようにしか見えない
だからこの例題見たときにイライラしてたんだよね
前提となってる仕様があるけど説明省いたとかそれ系かなと

19:
19/02/03 21:19:41.63 t4xt++Qj.net
>>13
では逆に質問しましょうか、そこから両者が部分的にでも合意できるポイントを探ることにしましょう
>>9
>fact 0 = 1
>fact n = n * fact(n - 1)
これをあなたはどのように解釈したかを、もう少し詳しめに記述していただくことは可能でしょうか、私の記述は今は >>13 が精一杯ですが、あなたの返答をみて改善できる点はないか検討したいと思います

20:デフォルトの名無しさん
19/02/03 21:20:07.09 RwDwNYzW.net
>>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

21:デフォルトの名無しさん
19/02/03 21:22:45.27 I0qputsI.net
>>15
fact 0で問答無用で終わる仕組みですが。。。
>>11 以上にやさしい説明はないと思われ。
普通の言語(ここで

22:
19/02/03 21:22:54.49 t4xt++Qj.net
>>18
終了条件は
>fact 0 = 1
です。関数 fact の引数が 0 なら、1 を関数の値として返し、fact の求値作業は終了します。
fact への入力が 1 でないならば
>fact n = n * fact(n - 1)
の定義をつかって、最初の入力 n よりも小さい値 n - 1 (< n) を使った関数定義がつかえるように変換します

23:デフォルトの名無しさん
19/02/03 21:25:18.35 5bolWXfM.net
>>19
理解したのは>>9の通りで
仮定として1かtrueを返したら再帰は止まる仕様になってると推測してる
>>20
だからfact(1)で無限に続いちゃうよね
1 - 1で fact 0をevalしてまたfact(1)になる
そこで終了条件が必要だけど何にも書いてないから記述通りならずーっと続く
としか見えないんだよね

24:デフォルトの名無しさん
19/02/03 21:26:42.72 DVkCUlxV.net
いやだから
fact 1 で1が出てくる でまた、fact 1になって永遠に続くとかの勝手な思い込みでしょ
あるいは、
fact 0 =1 になるから、また fact 1 -1 になると思ってるとか
だから、永遠に1が続くと勘違いしちゃっている

25:デフォルトの名無しさん
19/02/03 21:27:00.44 5bolWXfM.net
>>22
ということはやっぱり1を返したら必ず再帰は止まる仕様であってるのかな?
だったらすっきりするんだけども

26:デフォルトの名無しさん
19/02/03 21:28:01.94 DVkCUlxV.net
>>23
>1 - 1で fact 0をevalしてまたfact(1)になる
ならねーよ そこが恥ずかしいところだ

27:デフォルトの名無しさん
19/02/03 21:29:01.89 I0qputsI.net
途中で。。。
まあいい。
Pythonでも再帰出来る。
特別な話じゃない。
def fact(n):
if n == 0:
return 1
else:
return (n * fact(n - 1))

28:デフォルトの名無しさん
19/02/03 21:29:11.55 RwDwNYzW.net
>>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) とは絶対にならないからここで終わる
高校数学がわかるなら、漸化式と同じだと思えばよい

29:デフォルトの名無しさん
19/02/03 21:30:12.31 RwDwNYzW.net
>>25
そうそう。そのとおり。

30:
19/02/03 21:31:19.47 t4xt++Qj.net
>>23
>1 - 1で fact 0をevalしてまたfact(1)になる
>fact 0 = 1
というのは、関数 fact のうち fact(0) (引数が 0) のときの値は 1 である、と確定的な記述をしています。ここで答えが決まったので、さらに答えを求めるための関数適用作業には入りません、それはそういう意味です
どうして eval したあと fact(1) になる、と判断したのでしょうか?
fact(0) = 1 の 1 というのは fact() の値であって、fact の引数ではなく、また fact の引数になりうる記述は 「fact 0 = 1」という記述の中には見つからないのですが
>fact n = n * fact (n - 1)
この記述のなかには、たとえば 引数が 7 だとすると「 fact 8 を fact 7 の値をつかって表現する」ということですから、fact 8 を eval する「途中で」 fact 7 を eval しようとする、ということは書かれています

31:デフォルトの名無しさん
19/02/03 21:32:49.38 I0qputsI.net
>>25
その考えであってる。

32:
19/02/03 21:32:49.97 t4xt++Qj.net
>>25
「1 を返したら」とまるのではなく
fact 0 = 1
と fact の求値が、この行で確定しているから、止まるのです。
fact 0 = 100
という定義であっても、とまりますよ

33:デフォルトの名無しさん
19/02/03 21:33:05.02 5bolWXfM.net
>>28
いやいやfact(1)の評価は0なんだし
fact 0の定義があるからまた1
どう考えても続くんだよね
そもそも再起から脱出するためのコードがどこにもないから怪しいとも踏んでる
何か前提となってる仕様がありそうだ

34:デフォルトの名無しさん
19/02/03 21:34:47.28 5bolWXfM.net
>>29
やっぱりそうなんだ
そういう重要なことは早めに説明書きしといてくれないと大混乱だわ
まースッキリしたありがと
そういう仕様なら色々めんどくさいな・・・

35:デフォルトの名無しさん
19/02/03 21:35:32.72 RwDwNYzW.net
>>33
>いやいやfact(1)の評価は0なんだし
違う
どこにそんなことが書かれている?

36:
19/02/03 21:35:45.64 t4xt++Qj.net
>>33
>いやいやfact(1)の評価は0なんだし
ここが違っています。
fact(1) の評価は 1 * fact(0) であって、 0 じゃないです
fact(0) の値が具体的になにかは、fact(0) を意識しはじめた時点では分からないのですよ

37:デフォルトの名無しさん
19/02/03 21:37:12.79 PKgH5/Eo.net
バカ過ぎて泣けてくる…

38:デフォルトの名無しさん
19/02/03 21:37:24.99 DVkCUlxV.net
>>33
おもろいな だんだんネタに思えてきた
fact nの定義をよく見ろ 
fact 0 = 1 で再帰していないじゃん ここで止まるだろ 普通に考えれば
他の言語も一緒だろ ただそれをパターンマッチでやってるだけ

39:デフォルトの名無しさん
19/02/03 21:37:39.39 RwDwNYzW.net
>>34
えーと、すまん、「どんな場合でも」再帰は1を返したら終了すると考えているのなら
それは大間違いだ

40:デフォルトの名無しさん
19/02/03 21:38:05.69 I0qputsI.net
>>33
fact 1の評価は1 * fact 0
fact 0のみが再帰してない。(基底部)
再帰は再帰部と基底部が必ず最低1個ずつ存在する。

41:デフォルトの名無しさん
19/02/03 21:39:25.68 RwDwNYzW.net
>>23
>>>19
>理解したのは>>9の通りで
>仮定として1かtrueを返したら再帰は止まる仕様になってると推測してる
この推測が間違っているので、いったん忘れて素直にプログラムを読んでみよう

42:デフォルトの名無しさん
19/02/03 21:39:35.29 5bolWXfM.net
>>35
教えてもらったからもう大丈夫だよ
1で再起が止まる仕様なら納得だし
>>36
fact(1)を入力したら 1-1を評価するから fact 0
特に問題ないよ
1で止まる仕様らしいからそれを前提にコード考えないといかんのか・・
ややこしいことになるねこれ

43:デフォルトの名無しさん
19/02/03 21:41:09.23 RwDwNYzW.net
>>42
>>29>>31 でお墨付きを与えたのが間違いだった
君はまだ理解できていない (断言)

44:デフォルトの名無しさん
19/02/03 21:41:42.22 5bolWXfM.net
>>39
どーゆーこと
もうそれで覚えちゃったんだけども・・

45:デフォルトの名無しさん
19/02/03 21:43:10.37 RwDwNYzW.net
>>44
忘れろ
忘れてプログラムを読み直しな

46:
19/02/03 21:43:22.74 t4xt++Qj.net
>>42
>1で再起が止まる仕様なら納得だし
理解が不十分じゃないかと危惧します、その台詞「1 で再起がとまる」という言葉ですが、「何が」 1 で再起が止まる、と考えているのですか?
あなたの発言は、いちいち「何が」「どうだ」の「何が」が欠けているので不安です

47:
19/02/03 21:43:58.19 t4xt++Qj.net
>>44
覚える、という言葉はこういうときに使うものではないと思いますよ

48:デフォルトの名無しさん
19/02/03 21:44:56.66 RwDwNYzW.net
もういちど繰り返すが、
>>41 に書いたように
「仮定として1かtrueを返したら再帰は止まる仕様になってると推測している」
が大間違いだ

49:デフォルトの名無しさん
19/02/03 21:46:13.57 PKgH5/Eo.net
釣り宣言マダー?

50:デフォルトの名無しさん
19/02/03 21:46:48.03 5bolWXfM.net
>>45
それだと>>9の通りで揺らがない
>>46
この記述だと無限に *1が続くわけだから
なにか終了条件が必要なわけで
1を返したら再帰が止まる仕様ならなるほど納得

51:
19/02/03 21:47:09.11 t4xt++Qj.net
>>42
>fact(1)を入力したら 1-1を評価する
どうしてそう考えたのですか?そのような記述がどこに書かれていたのか説明いただけませんか?

52:デフォルトの名無しさん
19/02/03 21:49:35.33 DdA3Wm74.net
>>50
> この記述だと無限に *1が続くわけだから
何で?続かないが。ちゃんと読め。

53:デフォルトの名無しさん
19/02/03 21:49:54.21 5bolWXfM.net
>>48
大混乱してきた
1で再帰は必ず止まるんでないならさらにわからなくなるんだけども

54:デフォルトの名無しさん
19/02/03 21:49:57.06 DVkCUlxV.net
>>51
わかるじゃん fact 0で1が出てきたら、また、勝手に再帰させて
fact 1に戻っちゃう 勝手に脳内変換させちゃってる

55:デフォルトの名無しさん
19/02/03 21:51:42.20 5bolWXfM.net
>>51
fact(1)はfact(n-1)によってfact(0)になるよね
実は式自体が予想外の評価するってことなのかな?
いやまさかね・・

56:
19/02/03 21:52:52.90 t4xt++Qj.net
>>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 の求値で定義しているのです

57:デフォルトの名無しさん
19/02/03 21:53:28.07 RwDwNYzW.net
もしかすると、だけど
fact 0 = 1
を実行した直後に
fact 1 = 1 * fact 0
が続くと考えている?
もうしそうだとしたらそこが間違いで
fact 0 = 1
fact n = n * fact(n - 1)
はそのどちらかしか実行されない

58:
19/02/03 21:53:48.18 t4xt++Qj.net
>>53
>1で再帰は必ず止まるんでない
「何が」 1 で再帰が止まる、と考えているのですか?
「何が」の部分を答えてください

59:
19/02/03 21:56:12.46 t4xt++Qj.net
>>54
>fact 0で1が出てきたら、
何が 1 となるのか、そこをはっきり書いてください、「出てきたら」っていいますが、「何が」 1 と出てきたら、なんでしょうか?
>また、勝手に再帰させて
何が 1 となるのか、0 となるのか、そこをはっきりさせないことには、それ以降の思考は不可能ですよ、あなたには「また勝手に再帰させて」とかいうことを考える段階ではありません

60:デフォルトの名無しさん
19/02/03 21:57:58.25 5bolWXfM.net
>>56
ごめん意味不明わからん
>>57
もちろんそのように考えてる
fact 0 = 1の結果はすぐ反映されるんじゃないの?

61:デフォルトの名無しさん
19/02/03 21:58:56.17 DVkCUlxV.net
>>59
いや 俺は本人じゃないから
あくまでも、彼の脳内を勝手に想像しただけ 1がつづくケースを考えただけ
そのものでは無いかもしれないけど、どちらにしようが似たようなケースでしょ

62:
19/02/03 21:59:44.40 t4xt++Qj.net
>>61
これは失礼…

63:デフォルトの名無しさん
19/02/03 22:00:18.19 RwDwNYzW.net
>>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

64:デフォルトの名無しさん
19/02/03 22:02:19.10 5bolWXfM.net
>>63
いやいや終了条件が何も書かれてないから結局は続くよ
どのみちfact 0が1となるならまたfact(1-1)でfact(0)でしょ
間違ってないはずなんだけど何か使ってる人には常識的なお約束事とかあるのかな

65:デフォルトの名無しさん
19/02/03 22:02:55.82 DVkCUlxV.net
>>60
>fact 0 = 1の結果はすぐ反映されるんじゃないの?
ようするにそこでとまる
数学の階乗だから fact nの引数は再帰する度に-1される。
どこかで、factの引数が0になったら、それ以上は再帰しない
難しい話じゃないし、他の言語で再帰理解していたら、分かるはず
自分で落ち着いて考えてごらん

66:デフォルトの名無しさん
19/02/03 22:06:24.90 5bolWXfM.net
>>65
いやただのカウンターだったとしても止まらないし
やっぱりおかしいとは思う
何か前提がありそうな気はする

67:デフォルトの名無しさん
19/02/03 22:07:56.45 DdA3Wm74.net
>>64
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0 -- fact 0が・・
= 3 * 2 * 1 * 1 -- 1になる。factもうないのにここから何が続くの?
= 6

68:デフォルトの名無しさん
19/02/03 22:08:07.10 RwDwNYzW.net
>どのみちfact 0が1となるならまたfact(1-1)でfact(0)でしょ
fact 1 = 1 * fact (1-1) = 1 * fact 0
となるけど、これは fact 1 の時の処理だね
fact 0 の場合は 1 を返すだけだから、fact(1-1) という処理はもう出てこないよ
今の話は
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0
= 3 * 2 * 1 * 1
= 6
のうち
3 * 2 * 1 * fact 0

3 * 2 * 1 * 1
に変化するところだよ

69:デフォルトの名無しさん
19/02/03 22:08:36.79 DVkCUlxV.net
>>66
だとすると文法自体理解していない あるいは関数自体
もっと、詳しく書くと
>どのみちfact 0が1となるならまたfact(1-1)でfact(0)でしょ
定義を見てごらん
fact 0 = 1 でこれは、=の右にfactが無いからこれで再帰はしないで、ここで終了
fact n = n * fact n-1 で=の右にfactがあるから再帰する

70:デフォルトの名無しさん
19/02/03 22:10:11.03 5bolWXfM.net
>>67
= 3 * 2 * 1 * 1
= 3 * 2 * 1 * 1 * fact( 1 - 1 )
= 3 * 2 * 1 * 1 * 1 * fact ( 1 - 1)
どこまでも続くじゃない・・

71:デフォルトの名無しさん
19/02/03 22:11:04.78 DdA3Wm74.net
>>70
これはアカンよ…

72:デフォルトの名無しさん
19/02/03 22:13:50.28 DdA3Wm74.net
>>70
中学校の数学でそうはならないってことは習うから、学校の数学でそこまで勉強してからプログラミングに手を出しても遅くないのでは?

73:デフォルトの名無しさん
19/02/03 22:14:19.16 5bolWXfM.net
>>69
fact 0 = 1で終了するというのが納得いってない
もしそうであれば1を返せば再帰は終了すると仮定したんだ
そもそもfact 0 = 1ってマクロ定義みたいなもんだし
直ちに評価されて式に代入されるよね

74:デフォルトの名無しさん
19/02/03 22:17:47.65 DVkCUlxV.net
>>73
他の言語で再帰ってのは理解しているの?
fact 0 = 1で=の右にfactが無いから、再帰は終了 だから、終了条件は書かれている。
もしこれが理解できないのなら、関数定義とか、パターンマッチとかもっと基本的なことに
戻らないと理解できないと思う

75:デフォルトの名無しさん
19/02/03 22:18:13.63 5bolWXfM.net
>>72
プログラミング言語は数学じゃないから
再帰から脱出するならそのためのコードは絶対必要なはずなんだ
それがないってことは仕掛けがあるはずで
その仮定が1を返せば再帰から脱出できるという考え
でも違うらしいから大混乱してる

76:デフォルトの名無しさん
19/02/03 22:19:53.64 RwDwNYzW.net
>>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

77:デフォルトの名無しさん
19/02/03 22:21:37.72 5bolWXfM.net
>>74
Cで再帰させるなら終了条件にヒットしたらフラグたててreturnで戻ってく
関数定義の仕方ならサッと見たけど特に疑問はなかったよ
パターンマッチっていってもマクロ定義みたいなもんだし特にどうということも

78:デフォルトの名無しさん
19/02/03 22:22:31.24 RwDwNYzW.net
>>75
上に書いたけど、漸化式は理解している?
同じ書き方をします
Haskellは数学を基盤としているので、数学的な記述方法でプログラムが書けます
「再帰から脱出するならそのためのコードは絶対必要なはずなんだ」とあるけど、
もう書かれているよ
fact 0 = 1 って

79:デフォルトの名無しさん
19/02/03 22:24:44.77 5bolWXfM.net
>>76
いやだから・・
fact 0は1なんだからその次はfact(1)になるでしょ
何も間違ってないと思うんだけど。

80:デフォルトの名無しさん
19/02/03 22:25:28.82 RwDwNYzW.net
>fact 0は1なんだからその次はfact(1)になるでしょ
その次はもうないよ

81:デフォルトの名無しさん
19/02/03 22:26:23.52 5bolWXfM.net
>>78
それは終了条件じゃないよね
何が正解なのかさらに混乱して来た

82:デフォルトの名無しさん
19/02/03 22:26:31.18 DdA3Wm74.net
>>79
ならないよ。そこが間違ってるんだよ。

83:デフォルトの名無しさん
19/02/03 22:28:21.00 RwDwNYzW.net
>>81
君の言い方に合わせると「終了条件」と考えてよい
正しく説明すると
>>40 になる

84:デフォルトの名無しさん
19/02/03 22:28:40.54 I0qputsI.net
>>42
1で止まる仕様と言うか。。。
掛け算だから1を返すだけ(掛けても変わらない数)で、足し算なら0を返すよ。
sum1toN 0 = 0
sum1toN n = n + sum1toN (n - 1)

85:デフォルトの名無しさん
19/02/03 22:28:53.80 DdA3Wm74.net
>>81
終了条件だよ。
>>27のPythonコードで言うと
if n == 0:
return 1
の部分と同じだよ。

86:デフォルトの名無しさん
19/02/03 22:30:37.00 5bolWXfM.net
>>83
だから・・
fact 0は1なんだから続くじゃない?
延々と再帰するようにしか見えない

87:デフォルトの名無しさん
19/02/03 22:30:46.46 o+jOfHnE.net
この人の脳内だと、
fact 0 = 1

fact 0 = fact 1
になってるんじゃないだろうか

88:デフォルトの名無しさん
19/02/03 22:32:38.86 5bolWXfM.net
>>85
PythonやJavaは知らないのでなんとも

89:デフォルトの名無しさん
19/02/03 22:33:23.20 DVkCUlxV.net
この人 77で書いてるけど、文法まともに読んでないんだよ
Haskell 文法自体は一見綺麗で簡単そうに見えるけど
実際には、理解するのが非常に難しい(今回の再帰のとこじゃないんだけど)
適当に文法流し読みして理解しようとするのが 間違っている
もっとも、階乗の再帰は、他の人の説明で理解できるだろうと思うが

90:デフォルトの名無しさん
19/02/03 22:34:03.06 DdA3Wm74.net
>>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はいくつだ?

91:デフォルトの名無しさん
19/02/03 22:34:30.64 RwDwNYzW.net
うーん、C言語だと
int fact(int n)
{
if (n == 0) return 1;
else return n * fact (n - 1);
}
と書くのと同じなんだけどねえ

92:デフォルトの名無しさん
19/02/03 22:37:00.44 5bolWXfM.net
>>90
だから
=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は続くよ
だから色々納得いかないことあるんだけど

93:デフォルトの名無しさん
19/02/03 22:37:36.15 QPZpvG6g.net
もうHaskellはあきらめるんだ……

94:デフォルトの名無しさん
19/02/03 22:39:05.88 RwDwNYzW.net
>>92
この1行目はどこから出てきたの?
=3 * 2 * 1 * 1 * fact(1-1)
この辺を脳内でテキトーに処理してるからわからないんだよ
fact 3
のところから地道に書きながら置き換えてみな

95:デフォルトの名無しさん
19/02/03 22:41:48.43 5bolWXfM.net
>>94
それで地道にやったら >>9になったよ
あれ以外どうしろと・・

96:デフォルトの名無しさん
19/02/03 22:42:17.34 DdA3Wm74.net
>>92
算数のテストで
3 * 2 * 1 * 1は?って問題に、
3 * 2 * 1 * 1 * fact(1-1)って答えるの?
それは算数でも数学でもプログラミング言語でも間違いだよ。
算数でも数学でもプログラミング言語でも答えは6だよ。

97:デフォルトの名無しさん
19/02/03 22:42:33.19 RwDwNYzW.net
>>95
そうなのか。C言語はやったことがあるようだけど
>>91 は理解できてる?

98:デフォルトの名無しさん
19/02/03 22:43:47.92 5bolWXfM.net
>>96
そこはどうでもいいところだから書かなかった

99:デフォルトの名無しさん
19/02/03 22:43:59.88 RwDwNYzW.net
>>95
ああ、>>9 みたいに一気に展開するのではなくて、
fact 3 =
のところからひとつずつ地道に置き換えてみた?
もしやってないなら、今すぐやってみよう

100:デフォルトの名無しさん
19/02/03 22:44:48.18 RwDwNYzW.net
>>98
どうでもよくないから君は間違っている

101:デフォルトの名無しさん
19/02/03 22:45:27.31 5bolWXfM.net
>>97
あれでいいんだけど似たような制御構造がないよね
haskellのコードは全く別物に見える

102:デフォルトの名無しさん
19/02/03 22:45:46.73 wI7xL3t+.net
>>95
左辺から右辺に書き換えるって分かってる?

103:デフォルトの名無しさん
19/02/03 22:49:36.42 5bolWXfM.net
>>99
=3 * 2 * 1 * 1
=3 * 2 * 1 * 1 * 1
=3 * 2 * 1 * 1 * 1 * 1
・・・
やっぱり変わんないよ?
何かやってる人には常識だからあえて書いていないとかのお約束ごととかある言語なんじゃないかなぁ・・
パッと見た感じそんなに難しい言語には見えないけど内容に納得できない

104:デフォルトの名無しさん
19/02/03 22:50:08.66 PKgH5/Eo.net
>>98
どうでもよくないよ。正しい流れは、
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0
= 3 * 2 * 1 * 1
= 6
なのに、>>92によるとあなたは、
fact 3
= 3 * fact 2
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact 0
= 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)
であるという。
正しい答え6にたどり着かない原因はあなたが
3 * 2 * 1 * 1
= 3 * 2 * 1 * 1 * fact(1-1)
と変形(?)してしまっているところなのは明らか。

105:
19/02/03 22:51:43.03 t4xt++Qj.net
>>64
>またfact(1-1)
どうしてそのように推測したのですか?その 1 - 1 ってどこから誘導したのですか?

106:デフォルトの名無しさん
19/02/03 22:51:48.54 5bolWXfM.net
>>102
普通にやったけど特に問題なかったよ

107:
19/02/03 22:53:55.48 t4xt++Qj.net
>>79
>fact 0は1なんだからその次はfact(1)になるでしょ
ちがいますよ。なんども言っていますが「fact 0 は 1 」、っていう言葉が不正確ですね、fact 0 の「何が」 1 なんでしょうか?

108:デフォルトの名無しさん
19/02/03 22:54:17.35 5bolWXfM.net
>>104
fact 0 = 1とか定義されちゃってるから変形もなにもあの形にしかならんでしょう
>>105
fact 0の結果が1だからそれはすぐ反映されるので

109:
19/02/03 22:54:49.82 t4xt++Qj.net
>>86
>fact 0は1なんだから続くじゃない?
fact 0 の「何が」 1 なんですか?そこが他の者と違っている点かと思います

110:
19/02/03 22:55:58.80 t4xt++Qj.net
>>92
3 * 2 * 1 * 1 * fact(1-1)
その 1 - 1 はどういう理由で 1 - 1 と書いたのですか?

111:デフォルトの名無しさん
19/02/03 22:56:02.92 5bolWXfM.net
>>107
不正確と言われても他に言いようがないし

112:デフォルトの名無しさん
19/02/03 22:56:26.62 o+jOfHnE.net
Cでこんな感じに書いてあげれば分かるのだろうか。
int fact(int n) {
switch(n) {
case 0: return 1; // fib 0 = 1
default: return n * fact(n-1); // fib n = n * fact (n-1)
}
}

113:デフォルトの名無しさん
19/02/03 22:57:55.66 o+jOfHnE.net
あっとボケた。>>112のfibはfactの間違い

114:デフォルトの名無しさん
19/02/03 22:58:05.17 5bolWXfM.net
>>110
直前の結果が1なのでfact(n-1)に与えられてfact(1-1)
特に問題ないはずだけどもこれだけなら

115:
19/02/03 22:58:55.27 t4xt++Qj.net
>>111
あなたは 「fact 0 が 1 」といっていますが、我々は「fact 0 の値が 1」と「fact の引数が 1」とを別のものとして区別しているのです
あなたは区別していますか?あるいは「fact 0 が 1」というけれども fact 0 の何が 1 なんですか?

116:デフォルトの名無しさん
19/02/03 22:59:39.94 RwDwNYzW.net
>>114
>直前の結果が1なので
ここはOK
>fact(n-1)に与えられてfact(1-1)
ここが間違い。与えられるfact(n-1)がもう存在しない

117:
19/02/03 22:59:45.17 t4xt++Qj.net
>>114
結果は結果、引数は引数です
結果を引数に入れたり、引数を結果にいれたりしていないのですよ

118:デフォルトの名無しさん
19/02/03 23:01:37.23 5bolWXfM.net
>>112
なっ
まさかそういう意味なの?
fact 0 = 1
fact n = n * fact(n - 1)
のどちらかしか評価されないとか見ただけじゃわからないって!!
あーそういうことかー

119:デフォルトの名無しさん
19/02/03 23:01:49.80 PKgH5/Eo.net
>>108
> fact 0 = 1とか定義されちゃってるから変形もなにもあの形にしかならんでしょう
いいえその形には絶対になりません。
「fact 0 = 1とか定義されちゃってるから」
= 3 * 2 * 1 * fact 0

= 3 * 2 * 1 * 1
になります。うん、これはいい。次。
「fact 0 = 1とか定義されちゃってるから」
= 3 * 2 * 1 * 1

= 3 * 2 * 1 * 1 * fact(1-1)
になります?いいえ、なりません。勝手に足した「 * fact(1-1)」どっから出てきたんだ。
3 * 2 * 1 * 1は6です。

120:デフォルトの名無しさん
19/02/03 23:03:02.44 RwDwNYzW.net
理解できたようで良かったけど、結局は
>>57 がわかってなかったということだなあ

121:デフォルトの名無しさん
19/02/03 23:03:24.76 5bolWXfM.net
これは説明書きに書いておいて欲しかったなー
これじゃわかりようがないわ

122:デフォルトの名無しさん
19/02/03 23:03:29.59 PKgH5/Eo.net
>>118
よかったね。君へのレスで「パターンマッチ」を検索してごらん

123:
19/02/03 23:03:47.98 t4xt++Qj.net
>>118
そこでしたか!
うーん、それは見抜けなかったですね、いろいろしつこい質問をしてごめんなさい

124:デフォルトの名無しさん
19/02/03 23:04:21.15 RwDwNYzW.net
>>121
普通に数学の手法なので、数学を勉強しようか
(ちなみに、君以外は全員ふつうにわかってるぞ)

125:デフォルトの名無しさん
19/02/03 23:04:27.74 5bolWXfM.net
完全解決してスッキリ
みんな時間とらせてしまってごめん
そしてありがとう

126:デフォルトの名無しさん
19/02/03 23:06:11.09 RwDwNYzW.net
>>125 がんばれよー

127:デフォルトの名無しさん
19/02/03 23:06:13.09 9SI0qp6C.net
fact 0 = 1 は、fact 0 = fact (fact 0)ではありません。

128:デフォルトの名無しさん
19/02/03 23:06:37.09 PKgH5/Eo.net
>>120
>>60
> もちろんそのように考えてる
って書いてるけどそのように考えてなかったよね…

129:デフォルトの名無しさん
19/02/03 23:11:25.99 RwDwNYzW.net
>>122 が言っている「パターンマッチ」を彼が調べてくれるといいね

130:デフォルトの名無しさん
19/02/04 07:18:20.69 eX/1kX5o.net
>>92
だから、fact 1-1になった後、fact 0になるだろ?
そしたらfact 0 = 1になるんだよ。
数学の数学的帰納法ググれ。
fact 0 = 1
これはfactの引数が0なら強制的に1になると言ってる。
fact n = n * fact (n - 1)
これはfact nを解くには引数のnに、nより1つ小さい数をfactに渡したものを掛けたものと等しいと言っている。
(そして最終的にfact 0で1が返って全体の値が求まる)
fact 3
= 3 * fact (3 - 1)
= 3 * fact 2
= 3 * 2 * fact (2 - 1)
= 3 * 2 * fact 1
= 3 * 2 * 1 * fact (1 - 1)
= 3 * 2 * 1 * fact 0
= 3 * 2 * 1 * 1 ― fact 0 = 1より
= 6

131:デフォルトの名無しさん
19/02/04 07:24:43.06 eX/1kX5o.net
ただし、fact 0の様な特殊な条件を上に書く必要がある(Haskellに限らず、どの言語も)

132:デフォルトの名無しさん
19/02/04 07:30:26.48 eX/1kX5o.net
スタック消費しない末尾再帰とか、まだ先があるのに先が思いやられる。。。
(末尾再帰も最近じゃCやJavaScriptでも効くらしい。実質ループだから使った事ないけど)

133:デフォルトの名無しさん
19/02/04 11:21:38.86 66n6O4Xc.net
遅延評価や並行並列がデフォルトの言語ならばスタック消費しないのは当たり前である

134:デフォルトの名無しさん
19/02/04 11:34:48.97 nZpfKraZ.net
へっ?

135:デフォルトの名無しさん
19/02/04 11:56:25.98 66n6O4Xc.net
人間の読解力なんて順調に行っても1日1行程度でしかない

136:デフォルトの名無しさん
19/02/04 22:09:21.20 fVmYxPyX.net
>>133
代わりにスペースリークするけどな

137:デフォルトの名無しさん
19/02/05 00:47:55.71 YW+7XZmL.net
リストや配列には複数の要素がある
オブジェクトにも複数のメンバーがある
その一部が不要になってもメモリは全部残る
ここまでは言語に依存しない

138:デフォルトの名無しさん
19/02/05 02:19:00.11 .net
数日ぶりに覗いたらすっごいスレ伸びてる

139:デフォルトの名無しさん
19/02/05 03:02:15.20 /sjztfrr.net
ごいごいすー!

140:デフォルトの名無しさん
19/02/05 05:35:54.03 H17BJwTV.net
>>9,112,118 だけ読めばおk

141:デフォルトの名無しさん
19/02/11 10:04:55.57 3SqS2rDH.net
HaskelでWindowsアプリケーション作りたいですけどできるんですか?

142:デフォルトの名無しさん
19/02/11 22:30:07.24 njsDRqJy.net
問題は、何十年か前にそれができた人のコードを今コンパイルできるか
今できた人のコードを何十年後にコンパイルできるか
それができるのがC/C++で
他の言語はそれを不可能にして新しい言語を普及させたい

143:デフォルトの名無しさん
19/02/15 14:13:18.51 ZHz1cA+u.net
さようなら遅延評価 2019-02-15
URLリンク(kazu-yamamoto.hatenablog.jp)
Haskellがとっつきにくい原因の一つに遅延評価がある。入門書では、無限リストと遅延
評価がことさら強調される。しかし、Haskellを業務で使ってみると、遅延評価が煩わしく
なってくる。遅延評価なしでもほとんどのことは実現できるし、メモリーの使用量は推測
できないし、あまりいいことはない。(中略)
、GHC 8.0 では、言語拡張 Strict と StrictData が提供された。この二つを使えば、
デフォルトの評価戦略が正格評価となる。
つまり、以下のコードの評価戦略は遅延評価だが、Strict と StrictData を用いると
正格評価となる。(中略)
Strict と StrictData をもう少しく知りたい人はStrict Haskellを読んでほしい。
純粋関数型データ構造を読んだ諸君、Haskellではデフォルトが遅延評価だからイマイチ
例題をうまく実装できないと思ったことだろう。でも、今なら簡単にできるのだ!(後略)

144:デフォルトの名無しさん
19/02/15 14:59:49.72 h0RhILR4.net
ムグググググググ

145:デフォルトの名無しさん
19/02/15 16:33:48.53 iAmk1lDo.net
xcodeで使えないのが致命的なんだよな・・
リンクはできるがUIがらみのコードは書けないわけで

146:デフォルトの名無しさん
19/02/16 07:21:27.63 6iOnrs/B.net
スレを読み直してて気づいたけど、>>60ってこういう意味で言ってたのね
もちろんそのように(>>57の前半のように)考えてる
fact 0 = 1の結果はすぐ(fact n = n * fact(n - 1)に)反映されるんじゃないの?

147:デフォルトの名無しさん
19/02/16 09:09:45.75 pHmZSgK3.net
もういいだろう ただ単に基本的文法すら知らない子じゃん

148:デフォルトの名無しさん
19/02/16 13:13:23.08 aQjbCKoN.net
とっつきにくいも聞き飽きたな
パワハラ上司に同じこと言えるのかと
本当にとっつきにくい相手はそういう輩だ

149:デフォルトの名無しさん
19/02/16 13:16:38.83 CJGMkJvN.net
ややこしいことをややこしい方法で簡単にするのがhaskell

150:デフォルトの名無しさん
19/02/16 14:01:52.10 aQjbCKoN.net
Pythonのように型を書かないやつはゴミクズ
とかいうハラスメントが一番の問題だから遅延評価は誤差の範囲内

151:デフォルトの名無しさん
19/02/17 00:52:21.04 jxnSJIL4.net
一回しか変数に代入しない場合は副作用になりますか?
YES か NOでお答えください。
JavaScriptで言えばこういうコードです。
const a = foo(), b = bar(a), c = baz(b);
(const変数は再代入ができません)

152:デフォルトの名無しさん
19/02/17 00:52:52.45 KFkN1Yft.net
Haskellスレの皆さんこんにちは✨😃❗
突然ですがこのたびWeb制作板JavaScript質問スレにて、スレ民の総意により、
[1,2,3].map(v => (v += 2, v * v));
のv += 2は副作用ではない。
と決定しました!
ありがとう!ありがとう!

153:デフォルトの名無しさん
19/02/17 00:55:14.71 jxnSJIL4.net
>>152は再代入と(再代入しない)代入の違いがわからず
代入は副作用であると言い張っているマヌケが
再代入の例を出し、代入は副作用であると
結論づけようとしているだけなので無視してください。

154:デフォルトの名無しさん
19/02/17 01:04:11.22 KFkN1Yft.net
>>153
?別の方と勘違いされているのでは??
話はシンプル。質問をして、その答えを得た。以下が全てです。この質問と答えに、前後の文脈など関係ありますか??
904 Name_Not_Found sage 2019/02/17(日) 00:42:09.09 ID:???
>>901
悪いけど以下の(ア)に入るのは1か2か答えてくれる?1か2の一文字書くだけだから出来るよね?
[1,2,3].map(v => (v += 2, v * v));
のv += 2は(ア)である
1. 副作用である
2. 副作用ではない
907 Name_Not_Found sage 2019/02/17(日) 00:44:40.52 ID:???
>>904
Wikipediaの2つの成立条件を考えれば、2. は迷惑だろ
908 907 sage typo 2019/02/17(日) 00:45:33.97 ID:???
× 2. は迷惑だろ
〇 2. であることは明白だろ

155:デフォルトの名無しさん
19/02/17 01:06:42.19 jxnSJIL4.net
あの?Haskellスレを荒らさないでくれますか?
関係ない話はJavaScriptスレに戻ってください

156:デフォルトの名無しさん
19/02/17 01:13:02.79 KFkN1Yft.net
>>155
おや?
>>151を書き込んだのはどなたですか?w
何か都合の悪いことでもあったのですか?w
大慌てで>>151を張りに来たようですが?w

157:デフォルトの名無しさん
19/02/17 01:15:49.49 jxnSJIL4.net
>>151は単なる質問です。

158:デフォルトの名無しさん
19/02/17 01:25:17.93 KFkN1Yft.net
フフッw

159:デフォルトの名無しさん
19/02/17 01:47:05.17 bP6HzLuJ.net
うるせ~~~~一生代入してろ

160:デフォルトの名無しさん
19/02/17 03:04:30.74 lVDDSVXk.net
Haskellスレ民の方々どうも!
Web制作板JavaScript質問スレにて、
URLリンク(en.wikipedia.org)(computer_science)
の以下の文章について…
> One common demonstration of side effect behavior is that of the assignment operator in C++.
副作用の振る舞いの一般的なデモとしては、C++の代入演算子があります。
> For example, assignment returns the right operand and has the side effect of assigning that value to a variable.
例えば代入は右オペランドを返し、かつそれと同じ値を変数に代入するという副作用を持ちます。

スレ民の叡智を結集した結果、
・C++の代入演算子は副作用があるが、JavaScriptの代入演算子は副作用がない
・[1,2,3].map(v => (v += 2, v * v));
のv += 2は主作用を使っているのであって、副作用など使っていない!
と決定しました!
パチパチパチ~
ありがとー!!

161:デフォルトの名無しさん
19/02/17 13:09:25.08 C3KvaR2D.net
初期化と代入の違いはC++でさんざんやったやつだろ
C++には遅延評価がないから余裕じゃないのか

162:デフォルトの名無しさん
19/02/17 17:34:05.11 HZyuZSmb.net
runSTという魔法がある

163:デフォルトの名無しさん
19/02/20 10:51:29.01 FaK+gznk.net
Cのマクロ
#define fact(n) (((n)==0)?1:(n)*(fact((n)-1))
これだったら一見まともに見えて
実は無限ループする罠
fact(0)は
((0==0)?1:(0)*((((0)-1)==0)?1:((0)-1)*(....
となって無限ループ。
(ややこしいんで括弧の数とか間違って
るかもしれないけど)
C++でインライン関数で定義した場合は
論理式短絡評価で動くかもしれんが

164:デフォルトの名無しさん
19/02/20 11:35:48.52 FaK+gznk.net
再帰を含む関数がインライン展開されることを
期待するほうが間違いだったか...

165:デフォルトの名無しさん
19/02/20 11:43:51.95 KVaXFVJv.net
スレチ

166:デフォルトの名無しさん
19/02/20 16:55:25.36 xw22aw45.net
テンプレートメタプログラミングでもしてろクソ

167:デフォルトの名無しさん
19/02/22 10:09:30.67 ioyynd1U.net
花粉の時期に入るとみんなこれやり始めるよね

168:デフォルトの名無しさん
19/02/22 19:18:12.74 ioyynd1U.net
だめだわからん
fold_left :: (a -> b -> a) -> a -> [b] -> a
fold_left _ a [] = a
fold_left f a (x:xs) = fold_left f (f a x) xs
リストが a1 a2 a3のとき
folder_left f (f a a1) [a2 a3]
になることはわかる
その先の展開が何時間考えてもわからん
f(f(f(a,a1),a2),a3)になるってゆーんだが
イメージに繋がらない
お前らこんな難解なの本当に使いこなせてるの?
ここまでわかりにくいと有用なのか疑わしく思えて来る

169:デフォルトの名無しさん
19/02/22 19:43:58.95 LKaW/yz7.net
>>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でリスト作ったりするときの方かな

170:デフォルトの名無しさん
19/02/22 19:47:35.11 ioyynd1U.net
>>169
まったくわからない
例題載ってるとこにも似たようなことは書いてあるんだけども
ループで書くならすぐ終わる話だけど
ややこしすぎてイメージがつかめない
イメージがつかめたらその時点で理解終了なんだけど

171:デフォルトの名無しさん
19/02/22 19:51:15.80 ioyynd1U.net
a2とa3が分離されそうなことはわかるんだけども
folder_left f (f a a1) [a2 a3]
      ^^^^
こいつがどこ行くのっていうのと
どこをどうやったら()で括られることになるのかイメージできない

172:デフォルトの名無しさん
19/02/22 20:17:22.94 LKaW/yz7.net
>>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となる
これでどうだ

173:デフォルトの名無しさん
19/02/22 20:22:50.89 ioyynd1U.net
>>172
()の中って完全に展開されるまで実行されないものと思ってた
例題もそんな書き方だったし
これならわかる!
ありがとう

174:デフォルトの名無しさん
19/02/22 20:30:54.11 LKaW/yz7.net
>>173
そこらへんは評価戦略の話であって別件だね
再帰の本質ではないよ
Haskellといえば遅延評価みたいなところがあるから混乱しやすいけどね
上で言うならz3こと(f (f (f a a1) a2) a3)を、最後までこの形で持って行って、最後にまとめて計算するのが遅延評価
上で書いたみたく適宜評価していくのが正格評価
Haskellだとfolder_leftは二種類あって、
遅延評価版がfoldl
正格評価版がfoldl'
ぶっちゃけ左畳み込みに関してはfoldlを使うことはない
全部foldl'でいい

175:デフォルトの名無しさん
19/02/23 00:41:48.52 RiBir1w3.net
カリー化関数の意図がわからん
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:デフォルトの名無しさん
19/02/23 02:34:37.24 hS0A7KKk.net
>>175
やってるのは数式で書くと Σ[i=n..m] f(i) か
再帰をちょっと具体的に書き下さないと何のsumかわからんかった
それで多分やりたいのは
こういう風に個別の総和関数が手軽に作れますよみたいな話だと思う
タプルで定義されてるとこういう風にはいかない
(書けないことはないけどめんどくさい)
sumOfTwice :: Integer -> Integer -> Integer
sumOfTwice = sum_of (*2)
ここで(*2)とかできるのも
(*) :: Integer -> Integer -> Integer
がカリー化されてるおかげ
こういうのを部分適用と言って可変長引数とは異なる概念

177:デフォルトの名無しさん
19/02/23 02:59:05.43 RiBir1w3.net
>>176
(*2)の意味わからなくて前後調べたら演算子をカリー化できるとかあって
やっと意味わかったありがとう
しかも例題の先の先の方に有効な利用法書いてあったけど
なんかどうもサイトの進め方と合わないなー・・変えるかー
こんなこと書いてもなんか意味あんのだから何なんみたいな悶々パターンが多すぎる
とても簡単ですとか書いてあったら相当難しいフラグ確定
考え方が違うんだろうな

178:デフォルトの名無しさん
19/02/23 06:50:54.90 T/+XuHA6.net
考え方を変えるのが関数型を学ぶ一番の目的だと思うけど、
合わないなら関数型あきらめればいいじゃん。
うちは論理型言語に全く馴染めなくて、それに時間使うのやめた。

179:デフォルトの名無しさん
19/02/23 10:50:43.56 7gjHPQsv.net
そうじゃない
人を信じるのをあきらめて嘘を嘘と批判する
とても簡単ですと言った奴は嘘つきのクズであると

180:デフォルトの名無しさん
19/02/23 13:04:48.43 RiBir1w3.net
しかしいいサイト全然ないなどうしたもんか
お前らどうやって習得したのよこんな難解な言語

181:デフォルトの名無しさん
19/02/23 13:35:58.14 7gjHPQsv.net
例えばC#とF#の考え方は変わらないし
考え方を変えるというのも嘘だな
嘘に気付くのに1日かかるやつと5年以上かかるやつの差は大きい

182:デフォルトの名無しさん
19/02/23 14:01:38.38 E9HQXzXo.net
>嘘に気付くのに
ひどい世の中だな

183:デフォルトの名無しさん
19/02/23 17:11:04.23 RiBir1w3.net
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

184:デフォルトの名無しさん
19/02/23 17:12:26.05 RiBir1w3.net
>>183のクロージャの説明がさっぱりわからない
関数を生成する関数を簡単に作ることができるって言ってるんだけど
やってることは定義を繰り返してるだけでちっとも生成してない
どういう意味で関数を生成したって言ってるんだろ・・
Stringで関数生成してevalで評価しましただったらわかるんだけど、これ違うよね
それともhaskellの場合は関数定義は関数生成としているのか・・わからん
一体これは何が言いたいのか・・
実はどうでもいいことで気にしなくてもいいなら納得するんだけども

185:デフォルトの名無しさん
19/02/23 17:31:29.38 YUL1Jv8G.net
前スレに比べて明らかに初心者が多いのは何故だ

186:デフォルトの名無しさん
19/02/23 17:37:12.35 5fn4St+r.net
また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
てか何の言語なら知ってるんだっけ?

187:デフォルトの名無しさん
19/02/23 17:46:51.51 RiBir1w3.net
>>186
そうじゃなくてこれ関数定義だけで生成なんかしてないよね?って話
ぱっと見パスしてもいいようなどうでもいいことにも見える
そうであれば次に行く
どうもHaskellは納得いかないことがあまりにも多いんだ
文化の違いなのか考え方の違いなのかわからんけど
CかObj-CかSmalltalk-80/VisualWorksで

188:デフォルトの名無しさん
19/02/23 17:59:11.82 5fn4St+r.net
Cは実行時関数生成能力ないから仕方ないけど…
let foo10 = foo 10
は関数を返す関数fooに10を渡して、
関数(¥x -> x * 10)を得て(これが、ここが「生成」)
それにfoo10って名前を付けてるって理解は無理?
あなたこれまでに¥x -> x * 10って関数定義した覚えある?書いた覚えがあるのは¥x -> x * nでしょ?
まあ次行け次。

189:デフォルトの名無しさん
19/02/23 18:05:45.67 RiBir1w3.net
>>188
foo10は結局のところ ¥x->x*n を呼び出してるだけじゃないの?
¥x->x*10って関数を生成してないよね?
そういうことではない?

190:デフォルトの名無しさん
19/02/23 18:08:48.44 7gjHPQsv.net
C++だったらtemplate引数として渡したら定義で、コンストラクタに渡したら生成
静的と動的がわかるのが前提だからわからないならpythonかjavascriptから始めるべき

191:デフォルトの名無しさん
19/02/23 18:12:36.80 RiBir1w3.net
>>190
PythonならBlenderで頂点やマテリアル抽出するときに必須だったから使ったことあるけど
インデント縛りで胃が溶けそうだった
正直もうやりたくない・・

192:デフォルトの名無しさん
19/02/23 18:18:49.99 5fn4St+r.net
>>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の部分で。
(生成のタイミングは今回置いとくとして)

193:デフォルトの名無しさん
19/02/23 18:28:43.67 RiBir1w3.net
>>192
わかった!
無名関数で定義されてるからできるってことかー
納得できたありがとう
次行ってみる

194:デフォルトの名無しさん
19/02/23 18:29:48.03 7gjHPQsv.net
templateとコンストラクタとメソッドの考え方
関数と関数と関数の考え方
変わったのは見た目だけ

195:デフォルトの名無しさん
19/02/23 18:33:42.53 RiBir1w3.net
>>194
C++は全く知らないのでそっちはなんとも

196:デフォルトの名無しさん
19/02/23 18:51:02.51 RiBir1w3.net
早速詰まった何を言ってるのかわからん
一般に、関数を呼び出す場合、関数を評価するための環境は空リストです。
最初に、引数がこの環境に追加されます。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:デフォルトの名無しさん
19/02/23 19:26:38.79 hS0A7KKk.net
>>196
そこクロージャの説明のとこでしょ? 読み飛ばしていいと思うよ
手元にHaskellの入門書何冊かあるけど目次や索引にクロージャ無いし
純粋関数型言語でありデフォルトで関数がカリー化されているHaskellに
クロージャとかいう概念は別に要らないと思う
部分適用便利だねってことがわかればおk

198:デフォルトの名無しさん
19/02/23 19:34:16.40 RiBir1w3.net
>>197
そっかわかったありがとう!
関数の合成もすぐわかったのでさらに次行ってみる

199:デフォルトの名無しさん
19/02/23 20:14:35.45 RiBir1w3.net
データ型の定義まで来た
なんというかやっぱりこのサイトこれからhaskell入門の人にはどうでもいい余計なこと書きすぎなんじゃ・・
と思った

200:デフォルトの名無しさん
19/02/23 21:08:00.52 RiBir1w3.net
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)

201:デフォルトの名無しさん
19/02/23 21:24:41.95 24PtBhaW.net
>>200
いちいち躓いたところで立ち止まらない
これは別に関数型がどうとかに限った話じゃなく、未知のジャンルの勉強の話
まず思考を殺して30回読み返す
学ぶは真似ぶから始まる

202:デフォルトの名無しさん
19/02/23 21:25:53.99 RiBir1w3.net
納得しないと進まないタイプなので

203:デフォルトの名無しさん
19/02/23 21:31:22.65 24PtBhaW.net
>>202
じゃあモナドとflatMapを理解しきってからdo構文に進んでください
それ以外にないです

204:デフォルトの名無しさん
19/02/23 21:37:05.47 wr+1lm8V.net
読んでいるサイトが悪いのではないかなあ
すごいH本とか
HaskellではなくてOcamlだけど浅井『プログラミングの基礎』とかを読んだ方が
良いレベルだと思う

205:デフォルトの名無しさん
19/02/24 01:39:36.53 qI0VELUi.net
>>200
do は (>>=) の糖衣構文 (=分かりやすく見やすくするための別記法) なので最終的にはモナドと (>>=) を理解するまではしっくりこない。
URLリンク(qiita.com)

206:デフォルトの名無しさん
19/02/24 01:52:29.83 BExwBIrb.net
最終的に>>=演算子オーバーロードを理解する頃には難易度がC++と同じ

207:デフォルトの名無しさん
19/02/24 11:45:28.69 mBeDvEXM.net
>>205
そういうことなら先に進んでもよさそう
リンク先の見たら変換可能なこともわかった
ありがとう!

208:デフォルトの名無しさん
19/02/25 13:11:14.94 EIUHHo5S.net
haskellのGUIは何が主流なの
gtkじゃネイティブUIに見えないからqtahとか?
もしくはhaskellではGUIを扱わないとか?

209:デフォルトの名無しさん
19/02/25 21:33:28.52 jyEH5AtM.net
趣味でやってるが Threepenny 使ってる
簡単に組み合わせられるようになるかなと
Elm も学習中

210:デフォルトの名無しさん
19/02/26 21:42:21.10 DUz4HSDe.net
書籍「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 の型とは等しくないと思うのですが・・・

211:デフォルトの名無しさん
19/02/26 21:57:34.53 PosTOau2.net
to :: (b -> c -> a) -> ((b, c) -> a)
from :: ((b, c) -> a) -> (b -> c -> a)

212:デフォルトの名無しさん
19/02/27 01:02:26.71 2D6fGXPQ.net
Haskellにはファーストクラス多相関数がないから
idの型は単相なんだろう
単相のidという名前の同音異義語がちょっと多すぎるだけ

213:デフォルトの名無しさん
19/02/27 02:05:02.68 kdg0sG7A.net
>>209
思い出して今日発売のelm本、買おうかなと思ったら尼で売り切れててワロた。

214:デフォルトの名無しさん
19/02/28 17:06:29.75 W9NOQ7xg.net
下記の2つの関数の rank について
関数 f は rank 2、関数 g は rank 3 で合ってる?
f :: a -> (forall b. b -> c)
g :: a -> (forall b. b -> c) -> d

215:デフォルトの名無しさん
19/03/03 20:55:07.64 /obVPbHS.net
>>212
やっと意味が分かりました。
ありがとうございした。

216:デフォルトの名無しさん
19/03/03 22:40:24.54 iXSrdfon.net
条件を満たす限り畳み込むfoldWhileみたいな関数がないのはなぜ?
scanとtakeWhileで出来なくもないけど無駄なリストが生成されちゃうよね

217:デフォルトの名無しさん
19/03/04 10:06:50.76 P5wfz8lO.net
scanした後はlast.takeWhileとかだと思いますがfusionされるので作られません

218:デフォルトの名無しさん
19/03/04 11:18:43.16 yQsTNF7X.net
>>217
ありがとうございます
fusion調べてみます

219:デフォルトの名無しさん
19/03/09 09:51:28.74 KBqn1KqM.net
haskell入門ほぼ読んだけどちょっと物足りなくてもうすこしhaskell勉強したい欲がある(目的は競プロとか月並みにaiとか)
なんかええ本ある? 数学の高速なライブラリとか圏論、モナドの解説あるやつで(数学は拒絶反応しない)
get programming with haskellとか並行並列とか多少気になってるけどどう?

220:デフォルトの名無しさん
19/03/09 10:30:48.34 Vn/el/At.net
初心者を抜けた後、実践へ進みたいのなら幾つか勧められる本はある。
しかし、更なる勉強がしたいのなら、勧められる本はない。
初心者用か、初心者を抜けたばかりの者にはまだ難しい本しかない。
特に君の目的(競プロやAI)に叶う本は今のところ皆無だ。
なので、ネットを漁れ。
あと質問がやや曖昧で、何を求めているのか分からん。
数学の高速なライブラリの何を求めてる?
それを自作できる知識なのか?
活用する知識なのか?
もしくは、仕組みが知りたい具体的なライブラリでもあるのか?
圏論やモナドにしても然り。
それらの何が知りたいのか具体的に言ってみ。

221:デフォルトの名無しさん
19/03/09 11:02:47.64 KBqn1KqM.net
>>220
具体的には数学書のような理論本ですね 今のところ全然数学臭さがないので(コンピュータとは乖離してるかもしれないけど)
速度に関しては、命令型の書き方でないのでどうすれば速度が出る書き方が出来るかが一番興味あります
ai,競プロはやるとしたときの足掛かりが気になりました
このみっつのどれかが掘り下げられれば幸いです。

222:デフォルトの名無しさん
19/03/09 11:19:03.37 SKFKP+LU.net
THUNKとかWHNFとかだろうけど
俺もここら辺の本とかあるなら読んでみたい

223:デフォルトの名無しさん
19/03/09 11:28:44.92 Vn/el/At.net
>>221
「数学書のような理論本」 悪いが意味が分からん。
具体的に「何が知りたいのか」を言ってくれ。
理論と言うのが大雑派すぎる。
速度を上げる方法を学びたいのなら、
・Haskell High Performance Programming
・関数プログラミング 珠玉のアルゴリズムデザイン
この2つが正にうってつけだが、
「Haskell入門をほぼ読んだ」段階では挫折しそう。
AI や競プロは前レスでも言ったが本は無い。
AI は reinforcement leaning や deep leaning など技術範囲を絞ったワードと
haskell を組み合わせたキーワードでネット検索。
競プロは実際の競技で提出されたソースをたくさん読んで真似しろ。

224:デフォルトの名無しさん
19/03/09 11:50:40.66 KBqn1KqM.net
>>223
どうもありがとうございます。図書館で覗いてみます
具体的には、数学との関わりを体系だって書いてる書籍を探してましたが、そりゃ個々のキーワードで探す方が手っ取り早くて色々漁れますわな

225:デフォルトの名無しさん
19/03/09 13:09:34.75 HqfcKPNw.net
競プロにHaskellはどうなんだ…?
良くわからんけどSTモナド使いまくる感じになるのかな
あるいは珠玉のアルゴリズムを理解仕切った超人達の集まりなのか

226:デフォルトの名無しさん
19/03/09 13:43:47.24 w1EXpOnc.net
>>221,223
珠玉のアルゴリズムデザインへの入門としては同じ著者の
『Haskellによる関数プログラミングの思考法』
(旧版名は『関数プログラミング入門 ―Haskellで学ぶ原理と技法―』)
がいいと思う
他の入門書よりは数学色が強いし
等式変形によって効率を改善していく運算も割と丁寧に扱っていると思う
あとは『純粋関数型データ構造』とかも参考になるかも?
ただ競プロならSTRefとかSTUArrayとかに習熟するほうが
手っ取り早いし有力かも

227:デフォルトの名無しさん
19/03/09 13:49:45.09 Vn/el/At.net
>>225 >>226
例えば AtCoder の参加者のコードを見てみると分かるが、
STモナドなんて使ってるヤツはいない。
そもそも、haskell に慣れたら、STモナドなんて使いにくいだけだろ。
競プロみたいな短く速いコードを書く必要があるなら尚更。
珠玉本を理解しきった者かどうかは知らんが、
極端に短いコードで解いてくるヤツは、
どちらかといえば数学の知識が豊富なんじゃないかな。
問題文を数学の世界に落とし込む事に長けているように見える。
コンテストにもよるが、競技プログラミングは
個人的にはアルゴリズム力よりも数学力がより大事だと思ってる。
例えば Project Euler の高番号問題をシンプルに解けるヤツは競技も強そう。

228:デフォルトの名無しさん
19/03/09 15:47:05.82 KBqn1KqM.net
>>226 >>227
どうもありがとうございます。StateとかSTは内部処理はよくわからないけど便利なので使い方おぼえておきたいとこですね

229:デフォルトの名無しさん
19/03/09 20:50:02.63 2ErVpr0y.net
珠玉本難解すぎる
登場する学生達が天才過ぎる

230:デフォルトの名無しさん
19/03/10 04:06:11.50 0rKUQSsg.net
>>229
それでも理解したいのなら質問すればいい

231:デフォルトの名無しさん
19/03/14 01:49:52.87 pUnQtnNt.net
instance head ってよく聞くけど、
これは instance 宣言


232:のどの部分のこと? 例えば次の宣言の場合 instance (Foo a) => Bar (Baz a b) | a -> b where ・(Foo a) ・Bar (Baz a b) ・Bar (Baz a b) | a -> b ・instance キーワードと where キーワードの間の全部 ・その他 どれ?



233:デフォルトの名無しさん
19/03/14 02:00:29.34 pUnQtnNt.net
>>231
すまん、instance 宣言に関数従属は無いよな。
改めて、
instance (Foo a) => Bar (Baz a) where
この例だとどこが instance head なんだ?

234:デフォルトの名無しさん
19/03/14 08:32:21.91 pUnQtnNt.net
>>231
自己解決した。
instance head は => より右側かつ where より左側の部分だった。
スレ汚してすまない。

235:デフォルトの名無しさん
19/03/20 22:23:43.02 GM5azBbl.net
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

236:デフォルトの名無しさん
19/03/20 22:24:12.70 GM5azBbl.net
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

237:デフォルトの名無しさん
19/03/20 22:24:33.45 GM5azBbl.net
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

238:デフォルトの名無しさん
19/03/21 05:11:02.25 EnD5r7yP.net
コマンドラインでエンターを押すごとに数字が増えていく(Ctrl+C押すまで止まらない)
Haskellコード
main = mapM_ (\n -> print n >> getLine) [0..]

out:
0
1
2
3
4

239:デフォルトの名無しさん
19/03/21 22:17:24.35 2nCrXVEC.net
急にどしたんww
gtk2hsのドキュメントがHackageから消えてるのは気のせい?

240:デフォルトの名無しさん
19/03/21 22:23:19.66 NO+0ze73.net
なかなかGHC8.8出ないね

241:デフォルトの名無しさん
19/03/21 23:42:33.25 42YMN3yF.net
無限ポップアップ上げるやつ現れないとは高尚なスレ
リストで遅延評価使うのがなかなかハスケルっぽい

242:デフォルトの名無しさん
19/03/22 06:11:43.80 t/nkQ3ne.net
一応、カウンターみたいなのは純粋関数型言語には作れない言われてたから、作ってみた。
確かにi++みたいな事は出来ないが、違う方法で参照透明性を確保しつつ実現出来ると実感。
(個人的にHaskellには副作用はあると考えているが、参照透明性は崩れないとも考えている)

243:デフォルトの名無しさん
19/03/22 07:23:09.19 hntcvuv1.net
そりゃ副作用はあるよ。
じゃなきゃIO処理できない。
haskell の特徴は純粋な関数から副作用のある関数を呼べないこと。

244:デフォルトの名無しさん
19/03/22 07:32:41.43 t/nkQ3ne.net
うい。
そう言う仕組みになってるくせに、IOな関数も扱いとしては純粋な関数と同じ扱いなのが気に入ってます。
(型に気をつけていれば自然とそうなるし、普通にprint関数と純粋関数を関数合成出来るのが好き)

245:デフォルトの名無しさん
19/03/22 07:54:45.66 chPt0Ign.net
純粋関数型言語でカウンタが作れないというのは、
同じ関数を呼び出した結果がカウントアップされるような関数のこと。
pythonで書くとこんな感じ。
>>> def create_counter():
  n = 0
  def counter():
    nonlocal n
    n += 1
    return n
  return counter
>>> counter = create_counter()
>>> counter()
1
>>> counter()
2

246:デフォルトの名無しさん
19/03/22 08:09:16.10 t/nkQ3ne.net
>>244
そうなんですが、純粋関数型言語の場合、その関数を何回呼び出したのかカウントする関数を作るみたいな視点の切り替えで対処するのではと。
つまり自身のファイルを読み込んで自身(counter関数)を
a = counter
b = counter
a = 1
b = 2
に置き換える関数なら作れます。
欲しいのは結果であり、動作ではなく結果が同じなら良いと言う解釈です。

247:デフォルトの名無しさん
19/03/22 10:06:06.24 t/nkQ3ne.net
終了やカウントクリアに対応してみた。
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 ()


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch