5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

関数型プログラミング言語Haskell

1 :デフォルトの名無しさん:2001/07/26(木) 16:08
あまり馴染みのない人の多い関数型プログラミング。
Haskellを通じて、みんなで勉強しましょう。

2 :デフォルトの名無しさん:2001/07/26(木) 16:10
Haskellの公式HP
http://www.haskell.org
インタプリタHugs
http://www.haskell.org/hugs
日本語サイト
http://www.sampou.org/haskell
http://www.teu.ac.jp/kougi/koshida/Prog6/index.html

3 :デフォルトの名無しさん:2001/07/26(木) 16:12
参考スレ:関数型言語
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=987954395

4 :デフォルトの名無しさん:2001/07/26(木) 16:20
さくっと作ってみた階乗計算。
myfactorial 0 = 1
myfactorial n = n * myfactorial (n - 1)

関数myfactorialの引数が0の時、1を返し、
それ以外なら、n * myfactorial(n - 1)を返します。
再帰を用いて記述しております。
簡単すぎる例かな?

5 :デフォルトの名無しさん:2001/07/26(木) 16:32
参考図書
「プログラミング言語」

岩波講座  ソフトウェア科学〔基礎〕4

ISBN4-00-010344-X  岩波書店

武市 正人 著

菊判  248頁  本体 3,200円  1994年6月17日 発行

6 :デフォルトの名無しさん:2001/07/26(木) 17:05
関数型プログラミングっていいよね。
Lispのcondや、Haskellの | を読むとき、
その条件ごとの文の内容が、非常に読みやすい。

HaskellはLispと違って、中置記法じゃないのも自分としては良かったかな。

7 :石敢當:2001/07/26(木) 17:07
参考図書

>>1 「Haskellを通じて」

ということなので、Haskell以外でも良いのかな?

MLの本になりますけれど、次の本は効率の
良いコードを書くための大変良い参考書となりました。
(後半はほとんど読んでいませんが・・)
Haskellのコードを書く際にも役立つと思います。

Lawrence C. Paulson
"ML for the Working Programmer(2nd Ed)"
Cambridge University Press, 1996


面白そうに思ったので先日つい衝動買いしてしまった本が、

Chris Okasaki
"Purely Functional Data Structures"
Cambridge University Press, 1998

です。最初のほうをパラパラと斜め読みした程度
ですが、面白そうな匂いを感じました。

Haskellなどは趣味でいじっているだけなので、
なかなかゆっくり本を読む時間を取れません。
仕事で使う機会があれば・・という思いは
実現しそうにありません。

8 :1:2001/07/26(木) 17:27
あぁしまった
Haskellを通じてどうのこうの、じゃないっすね。
ちなみに、他の関数型言語に関しては、>>3 を参考にされると
よろしいかと思われます。

9 :デフォルトの名無しさん:2001/07/26(木) 18:19
Haskellで、「状態」を扱いたいときはどう組めばいいんでしょう?
プログラミングレベルでは「状態」でなくても、Haskellで構築された
アプリケーションのユーザーから見て「状態」はどうしても
あるわけですよね?
それをHaskellプログラミングではどのように対処したら良いのでしょう?

10 :デフォルトの名無しさん:2001/07/26(木) 20:43
関数型言語スレの25を引用すると…
>純粋な関数型言語(Haskell等)には代入がない。つまり状態はありません。
>ではどうしているかというと、mainルーチンを現在の計算機の状態をうけとり
>新しい計算機の状態を返す関数だと考えることで回避しています。

となっております。
…関数型言語の定義から勉強してきます

11 :デフォルトの名無しさん:2001/07/26(木) 21:41
たぶん 1 はもう知っているんだろうけど。

Why Functional Programming Matters
http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html

12 :名無しさん:2001/07/26(木) 21:45
じゃあ、とりあえず、
 モナ度がワケ、分か、らん┐(´_`)┌

13 :デフォルトの名無しさん:2001/07/26(木) 21:58
http://tanaka-www.cs.titech.ac.jp/%7Eeuske/scm/index.html
> Why Functional Programming Matters
> なぜ関数型言語が重要なのか、その利点をわかりやすく解説した ためになる文書。翻訳したいなあ。
してよ。

っつーか、やっぱ Haskell の前に英語勉強した方がいいよな。

14 :デフォルトの名無しさん:2001/07/26(木) 21:59
質問君ですみません。
foo :: Int -> Int
のような、関数の引数と返り値の型定義を行っても行わなくても
関数は実行できるのですが、これは実行速度の向上や、
不正な型が来たときにエラーを返すため、と考えていいのでしょうか?

15 :デフォルトの名無しさん:2001/07/26(木) 23:32
実行速度とかには影響無いです。>>14
(コンパイル速度は変わりそうだけど。)
fooの定義だけで入出力の型が決定すれば、
明示的な型宣言は必要無いんじゃなかったかな。
もし、型が曖昧であれば、コンパイル時に処理系がエラーを返す筈。

あと、haskellは静的型付けだから、実行時に不正な型とかで
エラーになる様な事は無い気がするけど。
Haskellでも動的型とかで実行時型エラーって起きるのかな?

16 :デフォルトの名無しさん:2001/07/27(金) 00:06
Haskell 入門は読んだはいいけど、
その先、親しみやすいサンプルプログラムがないんですよね。
他にも僕みたいな人は結構いると思うので
なんか面白いソースで短いのあったらみんなで載せていく、っていうのはどうでしょう。

17 :デフォルトの名無しさん:2001/07/27(金) 00:25
一生懸命、東工大の課題を解いていますが、
それの答えを載せてしまっては、東工大の学生さんに申し訳ないですよね

18 :Haskellを256倍……:2001/07/27(金) 00:32
Haskell本出ないのかなぁ。
つーか、1に出てる東工大の先生に書かせるしか。

19 :デフォルトの名無しさん:2001/07/27(金) 00:38
Hugs98使ってみようと思うんですが、
落とすファイルってこれだけでいいんですかね?
hugs98-Feb2001.zip
win32exes.zip
hugs.hlp
(コンパイラ(GHC)の方は大きい(22M)ので止めた)

20 :19:2001/07/27(金) 00:41
あ、winhugs.exe実行したら、無事窓が出て、
Prelude>
とプロンプトまでは出ました。

さて何しよう・・・

21 :デフォルトの名無しさん:2001/07/27(金) 01:13
とりあえず、東工大の演習問題で鍛えてみるのはいかがでしょう?

22 :デフォルトの名無しさん:2001/07/27(金) 01:47
>>20
ちなみに先に言っておくと、
そのHugsはソースファイルをエディタで作って、窓にドロップするしか、関数定義する方法はありません。
どうやっても環境中で関数定義はできないのでご注意を。

23 :デフォルトの名無しさん:2001/07/27(金) 05:09
東工大って>>2のこれ↓ですか。
http://www.teu.ac.jp/kougi/koshida/Prog6/index.html

24 :石敢當:2001/07/27(金) 11:48
>>8
やっぱりHaskellのみですね。すみません。

それじゃあ>>2からたどっていける所にありますが、次の本をあげときます。

The Haskell School of Expression(以下「SOE本」と記す)
http://haskell.cs.yale.edu/soe/


Haskellでは遅延評価を採用しているので無限リストを扱える・・
と読んでもピンと来ませんでした。

SOE本の無限リストに関する章に母関数を使ってフィボナッチ
数列を求めるExerciseがあります。つまり、

1/(1 - x - x^2) = 1 + x + 2x^2 + 3x^3 + 5x^4 + ...

x^nの係数がフィボナッチ数列の第n項となるというものです。

無限列に対する四則演算を準備しておけば、
a = [1, 0, 0,0,0,...(以下すべて0)]
b = [1,-1,-1,0,0,...(以下すべて0)]
fib = a / b
とするだけで上記母関数が得られます。実際にこのコードを
書いてフィボナッチ数列が出てきたときは結構感激しました。
C言語などではこんな風に無限列は扱えませんものね。

25 :石敢當:2001/07/27(金) 11:49
>>16 同感です。

>>17 コードの表現方法は幾通りもあるでしょうか、その中の
ひとつということでよろしいのではないでしょうか。掲載された
ものが自分のよりも良いコードであれば勉強になるし、自分の方が
良いと思って優越感に浸れるかもしれないし。
私はまだ東工大の演習は読んでいませんが・・。

26 :石敢當:2001/07/27(金) 12:41
誤)コードの表現方法は幾通りもあるでしょうか、
正)コードの表現方法は幾通りもあるでしょうから、

27 :デフォルトの名無しさん:2001/07/27(金) 13:12
東工大資料の「リスト」って所の課題3がね、
どうしたら一番スマートか、って悩んでる。
fillもfactもできているんだけど、どう出力するのが一番かな?と…
nもfact nも数字だから、文字列に変換しなければならないんだが、変換だるい(wara

28 :石敢當:2001/07/27(金) 15:15
>>27 変換だるい

showを使っておけばどうでしょ?
(例 show 12345 = "12345")

29 :無名λ式:2001/07/27(金) 16:22
> 実際にこのコードを書いてフィボナッチ数列が出てきたときは結構感激しまし
> た。C言語などではこんな風に無限列は扱えませんものね。

exact real numberって知ってる?

30 :デフォルトの名無しさん:2001/07/27(金) 17:29
東京工科大学じゃねぇか。
東工大と間違われるとは、幸せな大学だな。(w

31 :デフォルトの名無しさん:2001/07/27(金) 18:47
東京工科大学なんてドキュ大でHaskellを教えるのかぁ。

32 :デフォルトの名無しさん:2001/07/27(金) 19:56
>>29
詳しく教えてくれません?

33 :石敢當:2001/07/27(金) 22:18
>>29
不勉強にして知りません。名前からすると多倍長(無限)精度演算
ライブラリのようなものに思えますが、遅延評価を行えるもの
なのでしょうか。概略を教えて頂ければ幸いです。

34 :デフォルトの名無しさん:2001/07/27(金) 23:17
>>31
ドキュ大とは思わんが、トップレベルの大学ではないからわかりやすく説明してあるんだろ。
いいことじゃないか。東大だったら難しく書いてあるだろ。

35 :無能な姦理人@Shiri-Q:2001/07/27(金) 23:40
□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□
□□□■■□□□□□■□□□□□□□■■■■■■■■■■■■□□
□□■■□□□□□■■■■■■□□□□□□□□□□□□□■■□□
□■■□□■□□□■□□□□■□□□□□□□□□□□□■■□□□
□□■□■■□□■■■□□■■□□□□□□□□□□□■■□□□□
□□□■■□□■■□■■■■□□□□□□□□□□□■■□□□□□
□□■■□□□□□□□■■□□□□□□□□□□□■■□□□□□□
□□■□□□■□□□■■■■□□□□□□□□□□■□□□□□□□
□■■■■■■□□■■□□■■□□□□□□□□□■□□□□□□□
□□□□■□□□■■□□□□■■□□□□□□□□■□□□□□□□
□□■□■□■□□□□■■□□□□□□□□□□□■□□□□□□□
□□■□■□■□□□□□■■□□□□□□□□□□■□□□□□□□
□■■□■□■□□□□□□□□□□□□□□□□□■□□□□□□□
□■□□■□□□□■■■□□□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□■■■□□□□□□□□□□■□□□□□□□
□□□□■□□□□□□□□■■□□□□□□■■■■□□□□□□□





続きはコチラです
http://www.geocities.com/entry_k/main/main01.html

36 :デフォルトの名無しさん:2001/07/28(土) 06:11
haskellにもgcってやっぱ必要?

37 :デフォルトの名無しさん:2001/07/28(土) 06:38
というかGCある。

38 :デフォルトの名無しさん:2001/07/28(土) 07:09
>>35
おまえ生きる価値無し。死ね

39 :デフォルトの名無しさん:2001/07/28(土) 09:17
Cygwin上で噂のHaskellを使ってみるかー

~/hugs98/src/unix $ ./configure

無事通過。

~/hugs98/src $ make
gcc -c -g -O2 hugs.c
hugs.c: In function `initialize':
hugs.c:278: warning: assignment makes pointer from integer without a cast

あやしい・・・。

~/hugs98/src $ hugs
__ __ __ __ ____ ___ _________________________________________
|| || || || || || ||__ Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__|| __|| Copyright (c) 1994-2001
||---|| ___|| World Wide Web: http://haskell.org/hugs
|| || Report bugs to: hugs-bugs@haskell.org
|| || Version: February 2001 _________________________________________

0 [main] hugs 1256 open_stackdumpfile: Dumping stack trace to hugs.exe.stackdump
Segmentation fault (core dumped)

~/hugs98/src $ make install
unix/install-sh -d /usr/local/bin
unix/install-sh hugs /usr/local/bin
mv: `hugs' and `/usr/local/bin/#inst.1428#' are the same file
make: *** [install_bin] Error 1

インストールすらできねー俺になにか助言ない?

40 :デフォルトの名無しさん:2001/07/28(土) 11:02
>>39
何故コンパイルするの?
http://www.cse.ogi.edu/PacSoft/projects/Hugs/pages/downloading.htm#Win32

41 :デフォルトの名無しさん:2001/07/28(土) 11:06
Windous Installerで一発だったけど・・・なにか?

42 :39:2001/07/28(土) 12:16
もー、しょうがねーなー。
Windowsのバイナリの方つかうわい。

43 :無名λ式:2001/07/28(土) 14:38
>>33
無限精度の計算を行なう枠組です。
Haskel上の実装は遅延評価を用いています。
http://www.dcs.ed.ac.uk/home/mhe/plume/node95.html
http://www.dcs.ed.ac.uk/home/mhe/plume/
http://www.btexact.com/people/briggsk2/XR.html
言語が遅延評価を備えてない場合も実質的に同じ事をやる必要があります。

44 :デフォルトの名無しさん:2001/07/28(土) 16:26
>>39
WinのバイナリをCygwinの/usr/local/なんたら に置いて
/usr/local/binに、必要なプログラムのシンボリックリンク貼ればOKよ。

45 :名無しさん:2001/07/28(土) 16:47
何か、有りがちで単純なコマンドラインツールをHaskellで組み直して
「こんな感じで組めるぜ」と提示してみてくれよ。

46 :デフォルトの名無しさん:2001/07/28(土) 20:19
まずおまえがやれ>45

47 :デフォルトの名無しさん:2001/07/28(土) 20:51
非常に感動したのが、関数型言語スレで登場していたquicksortです。
これを転載します。
qsort [] = []
qsort (x:xs) = qsort [a|a<-xs,a<=x] ++ [x] ++ qsort [a|a<-xs,a>x]
これは、例えば[3, 2, 4, 6, 1, 8]なるリストがあるとき、
先頭の3より小さいもの[2, 1]と大きいもの[4, 6, 8]に分け、
小さい数字のリスト+先頭の数字+大きい数字のリスト、と結合します。
再帰前>[2, 1, 3, 4, 6, 8]
小さい数字リストと大きい数字リストは再帰呼び出しなので、
完全にソートされる、というわけです。
関数型言語故の、本質を忠実に表現している記述ですね。

48 :石敢當:2001/07/28(土) 22:21
>>43
ありがとうございます。無限精度の演算プログラムを作って遊んでいた
ことがあったので、XRに興味があります。私は高速乗算の実装で挫折して
しまいました。ここはHaskellのスレッドなのでこのくらいにしておきます。

>>47
A Short Introduction to Haskell(http://www.haskell.org/aboutHaskell.html)
に書かれているHaskellのQuicksortを見たときは、感激というよりも、
「えっ、こんな風に書けちゃうの!?」と驚異を感じました。それ以来、
ずるずるとHaskellの魅力に引きずりこまれています。
(と言うほど最近はいじっていないのですが…)

49 :無名λ式:2001/07/28(土) 23:33
>>47
> 関数型言語故の、本質を忠実に表現している記述ですね。

関数型言語というより、ZF記法とlist処理のpowerだと思われ

Prologも美しい。

qsort([], []):-!.
qsort([X], [X]):-!.
qsort([P|X], S):- partition(X, P, L, H), qsort(L,SL), qsort(H,SH),append(SL, [P | SH], S).

partition([], _, [], []).
partition([X|Y], P, [X|L], H):- X<=P, partition(Y, P, L, H).
partition([X|Y], P, L, [X|H]):- X>P, partition(Y, P, L, H).

;; partitionがZF記法の役割。[ | ]はLispの( . ) と同じ。

美しく感じるのは、要素の移動に相当する操作を、
ZF記法(と++)では陽に見えないconsとgcに任せているから。

50 :デフォルトの名無しさん:2001/07/28(土) 23:36
つかみんななに作ってんの?

51 :デフォルトの名無しさん:2001/07/29(日) 00:18
放っておいてよ!

52 :デフォルトの名無しさん:2001/07/29(日) 00:21
いや、今のところ勉強してるだけ。理由はかっこいいから(ワラ

53 :デフォルトの名無しさん:2001/07/29(日) 01:25
確かに出来上がったコードが数学的でカッコイイYO

54 :デフォルトの名無しさん:2001/07/29(日) 02:01
それより、Haskellを構築してる理論の中で難しい研究の成果を使ってるところがカコイイ

55 :デフォルトの名無しさん:2001/07/29(日) 11:44
パターンマッチで同じ変数を使えないのはなぜなんでしょう。

たとえば、リストの中からxをみつけて、それ以降の
リストを返す関数searchなるものを定義すると
search x [] = []
search x (y:ys)
| x==y = y:ys
| otherwise = search x ys
とするとOKなのですが、
search x [] = []
search x (x:xs) = x:xs
search x (y:xs) = search x xs
とすると
Repeated variable "x" in pattern
というエラーメッセージが出ます。

ちなみにPrologでは
search(X,[],[]).
search(X,[X|S],[X|S]).
search(X,[Y|S],Z) :- search(X,S,Z).
でOKなのです。

Prologのようにパターンマッチで同じ変数を使えると便利だと
思うのですが、どうして使えないんでしょうね?

56 :デフォルトの名無しさん:2001/07/29(日) 15:51
今日初めてHello,worldしてみた。
> の後にコードを書くってに驚いた。

57 :デフォルトの名無しさん:2001/07/29(日) 17:18
それって*.lhsのファイルですかね?
通常(?)の*.hsだと、>から始めないので平和です。

58 :56:2001/07/29(日) 17:27
>>57
そうそう、lhsで作った。
コード主体で書く方法は *.hs か、なるほど。
拡張子でフォーマットを判断しているわけやね。

59 ::2001/07/30(月) 02:33
このスレとか見てるとやっぱり関数型言語にこそプログラミングの未来があると思う。
象牙の塔とか言う人も多いみたいだけど、オブジェクト指向もそうだったんだし。

OOでは一部で「有機的なプログラミング」みたいな考え方があるみたいだけど
そういうのに不信感を抱くんだよね。

って単なるOO批判になってしまったけど。

60 :デフォルトの名無しさん:2001/07/30(月) 02:35
>>57
*.lhsの「>」形式のコードはクセがあると思いません?

61 :デフォルトの名無しさん:2001/07/30(月) 02:38
だれかRubyチックに「関数型スクリプト言語」作らないかな?
使いやすくして。

62 :デフォルトの名無しさん:2001/07/30(月) 02:59
>>59
何が言いたいのかさっぱり分からん。
オブジェクト指向言語と関数型言語は直交する概念だろ。

63 :デフォルトの名無しさん:2001/07/30(月) 03:05
>オブジェクト指向言語と関数型言語は直交する概念だろ。
状態を持つ/持たないという意味で対立しているようにも思える
解説してちょ

64 :59:2001/07/30(月) 03:57
>>62
だからこそ、今後のプログラミングにおける主要な概念は
関数型言語的なアプローチに移っていくだろう、と言いたいわけです。

65 :デフォルトの名無しさん:2001/07/30(月) 04:01
オブジェクト指向言語と関数型言語って関係あるの?

66 :デフォルトの名無しさん:2001/07/30(月) 04:04
>>65
むしろ排他的でしょう。

67 :デフォルトの名無しさん:2001/07/30(月) 04:20
じゃあ、>>62は何の事をいってるの?

68 :デフォルトの名無しさん:2001/07/30(月) 04:26
Haskellは人の名前なのね

69 :デフォルトの名無しさん:2001/07/30(月) 05:08
モナドって何ですか?食べ物ですか?

70 :デフォルトの名無しさん:2001/07/30(月) 05:11
最近関数型言語に非常に重要性を感じてたりするのですが、
日本語のHaskell解説書とかないんですかね?
だれか翻訳しないかな〜

71 :デフォルトの名無しさん:2001/07/30(月) 05:11
例えば、CSVファイルを読み込んで、各フィールドの合計値を出すだけのプログラムは
どう書くの?
漏れは、Stringをsplitする関数作っただけで疲れ切った。
つか、既存のモジュールにそういう関数(汎用的なwords?)があるのかどうかさえ分からんかったよ。トホホ
あと、Intを16進数の文字列として出力するにはどうするのか、教えてきぼん。

72 :無名λ式:2001/07/30(月) 15:25
>>60
> *.lhsの「>」形式のコードはクセがあると思いません?

Knuthの文芸的プログラミングの影響を受けて、
codeとdocumentを同時に書く、ってやりかた。
Mirandaにも同じようなモードがあった。

73 :デフォルトの名無しさん:2001/07/30(月) 16:36
>>71
実用的によく利用するI/Oのライブラリを整備することは、
実績のあるSchemeあたりでも立ち後れている分野ではあり
ますね。みんな関心がないんだろうなあ。

SML/NJには、yacc/flexをSML/NJで実装したライブラリが
あったと思いますけど、それあたりを参考にすればいける
のでは。

# と思いつつ、僕はHaskellに興味を持ってまだ3日なので、
# 具体的なコードはパス

74 :デフォルトの名無しさん:2001/07/30(月) 20:31
工科大学の演習問題(11/17)の2番がいまいちわからん。
下の通りでいいと思うんだけどなぁ。
iter :: Int -> (a -> a) -> a -> a
iter n f x = f (iter (n - 1) f x)
iter 1 f x = f x

75 :失業おやじ:2001/07/30(月) 20:47
>Intを16進数の文字列として出力するにはどうするのか、教えてきぼん

だるだるコードだけどこんなので
toHexCode x = map ("0123456789abcdef"!!) (toHex x)
toHex x
| q < 16 = q:r:[]
| otherwise = toHex q ++ (r:[])
where q = div x 16
r = mod x 16

ところで俺55だけど、パターンマッチングの仕組み誰か教えてきぼん

76 :デフォルトの名無しさん:2001/07/30(月) 21:03
>>75
55の質問には、仕様ですとしか答えられない自分(鬱
Prologは触ったことがないので間違いかも知れませんが、
Prologは論理を記述するから、同じ変数=同じものとなる(?)のでしょうが、
Haskellは論理記述とは少々異なる雰囲気を醸し出しているので…

参りました。降参します(鬱)

77 :デフォルトの名無しさん:2001/07/30(月) 21:51
>>66
HaskellにもSchemeにもオブジェクト指向機能があるけど?
OOってのは汎用的な抽象化技術に過ぎないから、特にコンフリクトするとは思わないけどな。
逆にオブジェクト指向型言語を関数型言語みたいな考え方で使うのも楽しい。

78 :71:2001/07/30(月) 23:38
>>75
あー、やっぱ自分でそういう関数書かなきゃだめか。
こういう基本的な関数は、普通の開発環境には付属してるような気がしたんだが。

79 :デフォルトの名無しさん:2001/07/31(火) 00:59
>>55 そりゃすべての typeが Eqのインスタンス (i.e. (==) を持つ)
であるとは限らないから。
でいいかな?
# 東工大で haskellを教えてる先生がいるかと思ってびっくりしたよ..

80 :石敢當:2001/07/31(火) 01:57
>>72
\begin{code} ... \end{code}で囲まれている部分にプログラムコードを
置き、それ以外の部分には任意のテキストを書けるというものですね。
ちょっと試してみたことがありますが、良いのかどうか、経験が浅くて
なんとも言えません。どなたかが作られたLaTeXのマクロもどこかに
あったように思います。

以前、HaskellのMLで "Literate Programming"というテーマが上がった
ことがありました。お名前は忘れましたが、\begin{code} ... \end{code}
のスタイルは全然ダメだ、ということを言っている人がいました。
どのような理由でダメだと言っていたのか忘れてしまいましたが、
個人的には毎行頭に > をつけるよりは書きやすいのではないかと
思います。(読みやすいかどうかは保留)

81 :石敢當:2001/07/31(火) 02:01
>>74
iter 1 f x の定義を iter n f x の前に持ってこないと再帰が
終わらないです。

大学の演習なので、本文で使っている foldr などを使うことを期待されて
いるのかもしれません。

iter :: Int -> (a -> a) -> a -> a
iter n f x = foldr (\x y -> f y) x [1..n]

[1..n]のリストは単にn回繰り返すためだけのものです。
(\x y -> f y)は引数x, yに対して f(y) を返す関数です。
(つまり、回数カウントのためだけのリストの要素 x を無視する)

あるいは次のように書いても同じです。

iter n f x = foldr g x [1..n]
where g x y = f y

(より簡単に where g x = f とも書けます)

82 : :2001/07/31(火) 05:59
まだ出てなかったので。

お勧め図書:

Conception, Evolution, and Application of Functional Programming Languages, P. Hudak, ACM Computing Surveys, 21(3):359-411.

関数型言語の歴史からHaskellに至るまでのお話が面白い。関数型言語の基本も易しく説明してくれます。

83 :デフォルトの名無しさん:2001/07/31(火) 14:44
英語ダメダメだけど、洋書買っちゃうゾ〜
お勧め洋書って何かありますかね?>石敢當さん

84 :デフォルトの名無しさん:2001/07/31(火) 14:48
HaskellでGtk+, Gnomeライブラリ群を紹介しているらしい
http://www2.ttcn.ne.jp/~aee0372/bindings/haskell.html

85 :石敢當:2001/07/31(火) 15:37
>>82
ぞのうち読んでみたいですが、これはACMの会員にならないと
入手できないものなのでしょうか。大学の図書館でも使えれば
いいのですが、大学関係者じゃないものですから・・。

86 :無名λ式:2001/07/31(火) 16:14
>>71
CSVか〜、関数型言語で使ったことねーよ。
"["と"]"で挟めばList型の表現だから簡単だな。

import IO
calcSum :: String -> Integer
calcSum s = (sum . fst . head) ((reads ("[" ++ s ++ "]")) ::[([Integer],String)])
printSum :: String -> IO ()
printSum s = putStr (show (calcSum s) ++ "\n")
main = do file <- openFile "test.dat" ReadMode
cvs <- IO.hGetContents file
rows <- return (lines cvs)
sequence_ (map printSum rows)

こんな感じでどう? (offside ruleに気を付けてねー)

IO _型を理解しないと単純なfilterも書けないよ。do, return, sequence_など。

>>55
pattern matchでの制限は、計算がprologと違い一方向であること、
eqの問題、lazinessを制御したいことがあること辺りが理由だと思うけどね〜。
実際、分解とmatchingのruleとformalなsemantics考えるのうっとうしいよね。
eqが複雑なdata typeの場合があるから。ruleによって関数のstrictnessが変わってくるでしょ。

87 :無名λ式:2001/07/31(火) 16:20
>>85
ほとんどの大学が身分証明書があれば入れるよ。事前に電話して聞いてみれば?
閉架か開架なのかも調べた方がいいな。開架じゃないといろいろ見れなくてつまらないでしょ。

>>86に、http://www.haskell.org/tutorial/書き忘れた。

88 :無名λ式:2001/07/31(火) 16:21
>>87
ああ、雑誌は学科の図書室にあるのか、図書館にあるのか、も。
図書館の所蔵で学科に置いてあるってのが良くあるパターンなので。

89 :デフォルトの名無しさん:2001/07/31(火) 17:14
CSVファイルをエディタでhaskellなりschemeなりのリストに書き換えちゃうのって
反則? ほとんど手間はないんだけど。

90 :石敢當:2001/07/31(火) 17:25
>>83 お勧め洋書って何かありますかね?>石敢當さん

Haskellの本で持っているのは >>24 に書いたSOE本1冊だけですので、
「これがいいよ」と薦められるほど知っていません。

本当は http://www.haskell.org/bookshelf/ に載っている、
Haskell: The Craft of Functional Programming または
Introduction to Functional Programming using Haskell を
予約するつもりで洋書屋さんに行ったのですが、たまたまSOE本が棚に
乗っていて、現物を見たら買わずにはいられず買ってしまったのです。
SOE本には"Learning Functional Programming through Multimedia"
という副題がついていて、Haskellでマルチメディアをやろうとは
思っていなかったので違う本にしたかったのですが、買って読んで
みたところ読みやすいように感じました。
Haskellの解説の章とグラフィックスを使った演習みたいな章が
交互に出てくるような構成になっていて、色々と楽しめました。
Hugs用のグラフィックスライブラリがあったのですが、最新の
"Feb 2001 version"では使えなくなっているようなのがちょっと残念です。

>>7 に書いた、Chris Okasaki氏の本ではMLのコードが使われて
いますが、巻末にHaskellのコードも掲載されていますのでHaskellの
学習にも使えるかもしれません。ただ、この本は私にとっては手ごわい
です。SOE本は「ふむふむ」とか「なるほど!」などと思いながら、時々
辞書を引いて読み進むことができましたが、Chris Okasaki氏の本は
やたらと知らない単語が出てくるので辞書を引いてばかり、まるで英語の
授業の予習をしているような気分になります。単に私の英語力がないだけ
なのですけれども、勝手ながらコンピュータの本は平易な文章で書いて
欲しいなと思いました。というわけで、こちらはほとんど読めていません。

書籍も良いですが、もしまだお読みになっていなければ
A Gentle Introduction to Haskell Version 98
を一度読まれると良いと思います。このスレッドのおかげで
邦訳( http://www.sampou.org/haskell/tutorial-j/index.html )が
あることを知りました。私もモナドあたりで挫折しているので、
邦訳版を読み直してみようかと思っています。

91 :石敢當:2001/07/31(火) 17:26
↑ごめんなさい。長すぎでした。

>>87
身分証明書は運転免許証などでいいのでしょうか?
ACM Computing Surveys を置いてあるかどうかも問題ですね。
そのうち調べてみます。ありがとうございました。

92 :失業おやじ:2001/07/31(火) 19:32
55だけど、76、86さんありがとさん。

パターンマッチのこと、俺も考えなおしてみた。
Prologは述語論理式で同じ変数が2度でてもおかしくないけど、
Haskellは関数で、仮引数に同じ変数が2度でると、確かに
おかしいな。
 述語論理式で f(X,X) としても全然OKだけど、
 関数の仮引数で f(x,x) とするのは確かに変な記述だ。

もうひとつ質問なんだけど、
エラーやら無限大やら、定義できない値を表現するTをさかさまに
した_|_というやつ、実際にHugs98でどのようにコードするの
か教えてくれ。

93 :デフォルトの名無しさん:2001/07/31(火) 20:14
f x
| エラーの起こる条件 = error "error message"
とかかなぁ。
これは簡単なエラーメッセージを出力する方法だけど、
エラー処理でしか書けないような?

94 :デフォルトの名無しさん:2001/07/31(火) 22:07
>>92
>エラーやら無限大やら、定義できない値を表現するT
lispならそういう場合、単に適当な未定義のシンボル
(infinityとか)置いておくだけだと思うけど、
haskellってそういう場合どうすんのかね。なんかあるの?

95 :デフォルトの名無しさん:2001/07/31(火) 23:52
オンラインで関数型言語周りのプログラミングの独学教材でいいのありますか?
やっぱりSICPとかいわれているSchemeのやつですか?

あれもpdf化されるとよさそうですけどね

96 :デフォルトの名無しさん:2001/08/01(水) 00:26
ところで、Concurrent Cleanって知ってますか?
並列プログラミングをサポートしたHaskellの発展形のような
感じのものなんですけど? どうでしょう?

97 :無名λ式:2001/08/01(水) 01:35
>>92
> エラーやら無限大やら、定義できない値を表現するTをさかさまに
> した_|_というやつ、実際にHugs98でどのようにコードするの
> か教えてくれ。

扱えない。そもそも未定義な値がbottomなんだから。
ある時に明示的に値を未定義にしたいならば、そこで、

bottom = bottom

とでも定義しておいて使えばいいけど、普通はexception使うよ。
ちなみにghcでこの式使うと無限ループでexceptionが起きるよ。

98 :無名λ式:2001/08/01(水) 01:37
>>89
やっぱ、一番敷居が高いのはmonadの考え方とその利用だと思うよ。
それさえこなせば、後は簡単。文字列操作は(効率はともかく)非常に得意。
なんせ文字列は文字のリストだから。リスト処理はギャフンと言うくらい強い。

99 :無名λ式:2001/08/01(水) 01:49
>>95
> オンラインで関数型言語周りのプログラミングの独学教材でいいのありますか?

>>90に上がっている奴でいいんじゃないの?
Monadは載ってないけど、武市正人(訳). 関数プログラミング. 近代科学社, 平成3年(1991).
(原著: R.Bird and P.Wadler. Introduction to Functional Programming. Prentice-Hall, 1988).
はめちゃ「(BakusのFP的)リスト遊び」が楽しい本。

100 :デフォルトの名無しさん:2001/08/01(水) 04:19
>>99
そういや、その訳者の人の授業受けたよ。

101 :デフォルトの名無しさん:2001/08/01(水) 06:48
>>96
ちょっとだけ説明があった
http://www.sra.co.jp/people/nishis/learning/fpl/stairway.html

102 :デフォルトの名無しさん:2001/08/01(水) 06:52
こっちから見た方がいいかも
http://www.sra.co.jp/people/nishis/learning/fpl/index.html

103 :失業おやじ:2001/08/01(水) 07:00
>>97
>扱えない。そもそも未定義な値がbottomなんだから。

やはりそうか。

「関数プログラミング」バード著にでてくる
擬リスト(partial list)なんかは表現できないわけか。

普通のリストは基底に空リスト[]をもってくるが、
擬リストは基底にbottom(さかさまT)をもってくる。

 普通のリスト 1:2:3:[]
 擬リスト 1:2:3:bottom

無限リストを擬リストのリストの極限と定義すると
便利そう。擬リスト使う方法だれか工夫してくれ。

104 :無名λ式:2001/08/01(水) 14:35
> 擬リスト(partial list)なんかは表現できないわけか。

これならpseudo bottomで十分だから、

bottom = bottom

でよい。
実際のbottomは、未定義になる式全体と同等である仮想的な対象。
∞みたいなもの。

105 :無名λ式:2001/08/01(水) 14:48
>>96
なにはともあれ、FAQ。
http://www.cs.nott.ac.uk/~gmh//faq.html#clean

並列系は総じて仕様が美しくない。ちなみにghcにもPVMで実行するoptionがある。
data parallelのNESL(http://www.cs.cmu.edu/~scandal/nesl.html)は面白い。

106 :失業おやじ:2001/08/01(水) 19:24
>>104
>これならpseudo bottomで十分だから

ほんとだ、コロンブスの卵だ

(1:2:bot) ++ (3:4:[]) where bot = bot

とすると [1,2 {Interrupted}

すごいすごい。partial list ですね。

このスレッドすごく役立つ。104サンキュー。

「関数プログラミング」すごくいい本だけど、haskellについては
触れていないことと、練習問題の解答がないことが難なんだよね。

107 :デフォルトの名無しさん:2001/08/01(水) 20:54
>>106
Web上に転がってるかもしれないですよ
(昔SICPの解答は見つけたので)

108 :無名λ式:2001/08/01(水) 22:47
ちょと訂正。

> 実際のbottomは、未定義になる式全体と同等である仮想的な対象。
> ∞みたいなもの。

未定義になる式「全て」。(そのような式の「集合」ではない)

109 :無名λ式:2001/08/01(水) 22:59
あと、>>86のprogram滅茶苦茶なseparationだな。恥かしぃ...

import IO
getList :: String -> [Integer]
getList s = (fst . head) ((reads ("[" ++ s ++ "]")) ::[([Integer],String)])
printlnInt :: Integer -> IO ()
printlnInt i = putStr (show i ++ "\n")
main = do file <- openFile "test.dat" ReadMode
cvs <- IO.hGetContents file
rows <- return (lines cvs)
sequence_ (map (printlnInt . sum . getList) rows)

こうしないと機能単位に分かれてないな。U2 that she know...

-- hGetContentsの関数名は処理系選ぶと思います。GHC 5.0を使ってます。

110 :失業おやじ:2001/08/02(木) 21:45
型、型変数、型コンストラクタ、型クラスの関係がわからん。
Javaにたとえれば 型がクラスで、型変数がオブジェクト、
型クラスがスーパークラスないしインターフェースといった
ところか。でもいまいちJavaにたとえるのは概念的に違う感じ
もあるな。このへん すっきりした説明 お願い。

111 :デフォルトの名無しさん:2001/08/02(木) 21:54
>>110
型変数とオブジェクトはまるで違うものだろ。

112 :失業おやじ:2001/08/02(木) 21:56
型のお勉強のため自然数型を作って、
たし算とかけ算の証明をしてみた

data Sizensu = Zero | Next Sizensu deriving (Show)
tasu Zero x = x
tasu (Next x) y = Next (tasu x y)
kakeru (Next Zero) x = x
kakeru (Next x) y = tasu (kakeru x y) y

2+3=5は
tasu (Next (Next Zero)) (Next (Next (Next Zero)))
-> Next (Next (Next (Next (Next Zero))))

2 * 3 = 6は
kakeru (Next (Next Zero)) (Next (Next (Next Zero)))
-> Next (Next (Next (Next (Next (Next Zero)))))

ということで、正の数については順調。

で、負の数も含めて整数型に拡張したいのだが、これなかなか
うまくいかない。
(−2)* (−3)= 6
をやってみてくれ。

113 :失業おやじ:2001/08/02(木) 22:11
>111
>型変数とオブジェクトはまるで違うものだろ

型がクラスとすると、型変数は型の要素だからオブジェクト
と、単細胞に思ったが、違うと言われればそうだな。
型変数は型の要素ではなく、変数だから型のハンドルか。
ということはクラスか。

いかん、混乱してきた。

114 :無名λ式:2001/08/02(木) 23:43
>>110
type: 一般名詞としての型あるいはHaskellの単純型

type class: Haskellにおけるクラス
constructor class: Haskellにおけるクラス(Jonesによる新用語)

type constructor: Haskellにおけるコンストラクタ
constructor: Haskellにおけるコンストラクタ

type variable: 型を値にとる変数

>>112
負の数を表現できない"Sizensu"で、負の数を扱おうとするのは無理難題。

115 :デフォルトの名無しさん:2001/08/03(金) 03:47
型変数は C++のtemplateにおける...なんていうんだ。述語知らん。
Javaには現在ない概念。JDK1.5になったら入るかも?

type constructorは型を取って型を返す関数のような
[]: *→* (,): *→*→* (か?)
constructor classは type constructorのクラス (特定の操作を持ったもの)
だね。mpjえらい。つーかそのために gofer作ったってほんとか?

goferの source見ると、8086の compactモデルで使えるように、TurboCで
compileできるように書いてあってちょっと嬉しかった。当時 DOS machineしか
持ってなかったし。

116 :失業おやじ:2001/08/03(金) 06:12
>>112
自己レスだけど、「関数プログラミング」に以下のような
感じで書いてあった。

自然数はゼロとある数の次の数を指定する方法で作成できる。
マイナスを含めた整数は自然数にある数の前の数を指定する方法を
追加するとできると思うだろうけど、でもそれではなかなかうまく
いかないんだよ。
これ練習問題にとっとくから、自分でやりなさあい。
まいった。

117 :デフォルトの名無しさん:2001/08/03(金) 11:19
つーか基礎数学論の領域に入ってきてるような、、、
関数言語ってそのための物なのか?

118 :デフォルトの名無しさん:2001/08/03(金) 12:12
つーか基礎論そのものが、もはやコンピュータサイエンス用の応用数学じゃん。

119 :石敢當:2001/08/03(金) 15:31
工科大のテキストを読んでいます。

11/17の課題より:
「整数リストに対し,正の要素の2乗の和を返す関数を定義せよ.」

これは簡単に書けます(インデントが分かるように > を入れました):

>func1 :: [Int] -> Int
>func1 [] = 0
>func1 (x:xs)
> | x > 0 = x * x + func1 xs
> | otherwise = func1 xs

やっていることは明らかだと思います。
ただ、リスト処理関数 zip, filter, map などの説明の後にある
課題ですので、これらを使用した定義が期待されているのでしょう。
次のようなものを作ってみました。

>func2 :: [Int] -> Int
>func2 xs = sum (map (\x -> x * x) (filter (> 0) xs))

これも右辺を右側から見ていくとやっていることは明らかです。まず
filter で正の要素のみを抽出し、map で各要素を2乗し、sum で和を求める。
しかし、filter, map の処理が終わるたびに新しいリストが生成され、
func1 よりも効率が悪いのではないか、という気がします(本当かな?)。

(続く)

120 :石敢當:2001/08/03(金) 15:35
(↑の続き)

func2 をちょっと書き換えると次の定義が得られます:

>func3 :: [Int] -> Int
>func3 = sum . map (\x -> x * x) . (filter (> 0))

func2 と func3 とでは、処理効率に違いがあるのでしょうか。
いずれ profiler でも使って調べてみたいところです。

また、これら3つの定義に(処理速度以外の点で)何か優劣が
あるでしょうか。

121 :デフォルトの名無しさん:2001/08/03(金) 17:34
>>119
func1 のほうが中間のリストを生成しない分効率がいいと思います。
deforestation とかなんとかいう(うろ覚え)最適化の手法は、
func2 のような中間構造の生成を回避して、func1 のような定義を
導く手法ではなかったかなあ。言葉だけ覚えていて、内容をしらない。^^;;

122 :失業おやじ:2001/08/03(金) 21:15
>>120
3つとも処理効率はほとんど同じと思う。
リストの長さをNとすると、O(N)だろう。
>>121
>func1 のほうが中間のリストを生成しない分効率がいいと思います
Haskellは最外簡約法だから、この場合Lispと違って中間リストなんか
生成しないだろう。

違ってたらごめん。

123 :失業おやじ:2001/08/03(金) 21:52
型変数まだよくわからないが、
現時点で型変数についての想像を書くと

CとかJavaとかでは int x; と書くと、xは整数型の変数で
1とか2とか−999とかを指示するものなのだが、
型変数というのは、その型の要素を指示するようではない
らしい。その型そのものを指したり、その型から継承される型
を指したりするんじゃなかろうか。

124 :デフォルトの名無しさん:2001/08/03(金) 22:13
ちゃんとした本読んだ方がいいんじゃない?>123

125 :デフォルトの名無しさん:2001/08/04(土) 03:01
>>119-122
hugsで試したところ、func1が 89reductions
func2が 96reductions
func3が 98reductionsでした。
ただ、リストの中の負の数が増えると func3が func1を下回りました。
まあよくわかんないけど、func3の書き方が関数型っぽくて
かっこいいと思いました。

126 :デフォルトの名無しさん:2001/08/04(土) 04:00
>>118
なーるほどね、納得

127 :失業おやじ:2001/08/04(土) 07:24
>>121
ごめんよ。おれ122だけど、言っている意味取り違えた。
「中間のリストを生成」をリストの結果を生成と読んでしまった。
121の言っているのは (a:bottom) bottomはこの場合、まだ計算
や簡約されていないものを指す。 という意味のリストを生成する
と言ったんだろう。

128 :失業おやじ:2001/08/04(土) 07:34
>>125
無限リストに適用して速さ比べするのは

たとえば、[1,-2,3,-4,5,-6....] といったリストの部分リスト
のリストを作ってfunc1,2,3を適用してみると

inits [] = [[]]
inits (x:xs) = [[]] ++ map (x:) (inits xs)
func1' xs = map func1 (inits xs)
func2' xs = map func2 (inits xs)
func3' xs = map func3 (inits xs)
suretu :: [Int]
suretu = [ (-1)^x * x | x <- [1..] ]

func1' suretu -> 0,0,4,4,20,20,56,56....

129 :日曜 Haskeller オヤジ:2001/08/04(土) 13:44
初心者です、私も仲間にいれてくれ〜
ど素人質問です
http://www.teu.ac.jp/kougi/koshida/Prog6/Text03/index.html
ここ読みながらやってるんですけど、

type hoge = ( Int , Int )
maxThreeAux :: Int -> hoge-> hoge
maxThreeAux a b
  | a < fst( b ) = b
  | a == fst( b ) = ( a , snd( b ) + 1 )
  | a > fst( b ) = ( a , 1 )

maxOccursThree :: Int -> Int -> Int -> hoge
maxOccursThree a b c = ( maxThreeAux a ( maxThreeAux b
  ( maxThreeAux c ( 0 , 0 ) ) ) )

とすると type の行でエラーがでるんです。
type ってどこに書けばいいんでしょう?

すなおに、これなら動くんですけど・・・
maxThreeAux :: Int -> ( Int , Int ) -> ( Int , Int )
...

130 :デフォルトの名無しさん:2001/08/04(土) 13:51
>>129
http://www.sampou.org/haskell/tutorial-j/goodies.html
> 読者のみなさんは気づいたでしょうか、特定の型を表わす識別子は大文字ではじまっています。たとえば、Integer や Char です。また、 inc のような値を表わす識別子は小文字ではじまっています。これは単なる習慣ではありません。Haskell の構文規則でそうすることになっているのです。また、先頭の文字だけではなく、そのほかの文字も、大文字か小文字かということは重要で、foo と fOo と fOO はすべて違う識別子として区別されます。

hoge を Hoge にしなされ、ってこと。

131 :日曜 Haskeller オヤジ :2001/08/04(土) 13:57
>>130
おお、早速のレスありがどうございます。
もう三十半ばも超えて、プログラマだいぶもうろくしとります。
早速試したところ、巧くいきました。

132 :失業おやじ:2001/08/04(土) 16:34
Haskellの文法についての日本語解説書がなくて困っていたが、
よい本があった。
 岩波講座ソフトウエア科学4 プログラミング言語
 武一正人著 3000円
著者は「関数プログラミング」の訳者。
プログラミング言語全般の特徴を関数型言語をメタ言語として
解説するということですが、実際上関数型言語の解説書となって
おります。
HaskellではなくGoferの解説となってますが、文法はまったく
同じみたいです。このままHaskellの教科書になるような感じ。

133 :失業おやじ:2001/08/04(土) 17:06
<<132
大事なこと書くの忘れた。
オレこの本読み始めで、まだ30ページしか読んでない。
132はその上での感想。

古本屋(明倫館)で2000円でゲットしてきた。

134 :かーくん萌え:2001/08/04(土) 19:02
http://www.geocities.co.jp/SiliconValley-Oakland/1866/

135 :無名λ式:2001/08/05(日) 02:59
>>121
リストを食って、結果を生成する状態遷移機械に翻訳します。
http://www.research.avayalabs.com/user/wadler//topics/deforestation.html
Wadlerの初期の論文の方がこれより着眼点が分かりやすいです。

136 :無名λ式:2001/08/05(日) 03:02
>>116
Nextだけじゃなくて、Prevも作って、
data Seisu = Zero | Next Seisu | Prev Seisu deriving (Show)
するだけですよ。後は力業。

純粋λ計算でやる時はもうちょっと違うやりかた。

137 :デフォルトの名無しさん:2001/08/05(日) 08:46
>>136
Church Numerals ? これって、負の数はどう表現するんですか。

138 :デフォルトの名無しさん:2001/08/05(日) 23:50
IOモナドはなんとなくわかるが
それ以外のモナドはなんのためにあるのかわからん。

誰か教えて。

139 :138:2001/08/06(月) 01:31
http://calypso.score.is.tsukuba.ac.jp/~okuma/functional/monad.html
なんとなくわかったような、わからんような…

140 :デフォルトの名無しさん:2001/08/06(月) 15:36
>>139
このリンクの人わかってないね.
副作用である状態遷移と関数の入出力を混ぜて説明しちゃいかんよ.

141 :デフォルトの名無しさん:2001/08/06(月) 16:04
>>140
状態遷移を副作用と呼ばずに、関数の入出力ということにしよう
ってのがモナドなんだから、良いんじゃないの?

142 :デフォルトの名無しさん:2001/08/06(月) 16:54
age

143 :デフォルトの名無しさん:2001/08/06(月) 20:22

  ∧_∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ( ´∀`)< モナドって何モナー
 (    )  \_________
 | | |
 (__)_)

ああっ、つい。ごめんなさい…。

144 :デフォルトの名無しさん:2001/08/06(月) 22:26
イスラエルの諜報機関だ。
…くっ、ノックの音がする。後は頼んだ……ぐはっ

145 :無名λ式:2001/08/06(月) 23:16
>>137
> Church Numerals ? これって、負の数はどう表現するんですか。

2 ≡ λfx.f(fx) ってやり方の延長だと負の数は無理です。

146 :デフォルトの名無しさん:2001/08/06(月) 23:30
>>144
あー、最初なんのことだかサッパリわからんかったよ。
一応、、、

それはモサドだろっ!!

147 :ドキュソ:2001/08/06(月) 23:35
関数型言語やるならラムダ計算とかの勉強もしたほうがいいのか?

148 :デフォルトの名無しさん:2001/08/07(火) 02:11
したほうがいい、っていうか自然にやることになるのでは。
SNとか Yコンビネータは知らなくても大丈夫だとは思うが。

149 :ドキュソ:2001/08/07(火) 02:23
>>148
やはりそうですか。

↓がよく理解できず鬱です…。
http://members.tripod.co.jp/nbz/ref/lambda.html

150 :石敢當:2001/08/07(火) 15:08
>>125
調べて頂いてありがとうございました。

>>138 それ以外のモナドはなんのためにあるのかわからん。

十数年前、初めてC++の本を読んだときもあまり理解できませんでした。
書いてある中身自体(例えばクラスとそのメンバ)については分からなくも
ないのですが、一体クラスの何が便利なのか?ありがたいのか?という
ことを実感として得られなかったのです。
Monadについても似たような感じを受けています。便利さ・ありがたみを
実感できるときっと「分かった」という気になれるのでしょう。

>>144
板間違えかと思いました。>>146を読むまで気づかなかった…

151 :デフォルトの名無しさん:2001/08/07(火) 15:36
'`'を使って第二引数を部分適用するのは邪道なんだろうか?
(`map` [1,2,3,4]) (<3)

あと、'-'の第二引数を部分適用できないのがちょっと…
(+ (-7)) みたいに書くのもなんかなぁ。

152 :石敢當:2001/08/07(火) 16:32
>>151 あと、'-'の第二引数を部分適用できないのがちょっと…

(+ (-x)) のように書いても勿論OKですが、このような場合のために
subtract :: Interger -> Interger -> Interger がPreludeに用意されて
います。去年のメーリングリストで知りました。
http://www.mail-archive.com/haskell@haskell.org/msg06737.html

153 :日曜 Haskeller オヤジ:2001/08/07(火) 20:59
>>149
そのページの別のところでIE5のブラウザがクラッシュするページがあるよ、
修正してもらえるとうれしいのぉ。
せっかく興味深いページなのにのぉ。
ついでにトライポッドは広告ウインドウがウザイのぉ。
読ませてもらってる分際でいうことじゃないけど・・・

154 :無名λ式:2001/08/07(火) 23:47
>>151
> あと、'-'の第二引数を部分適用できないのがちょっと…

二項演算子と単項演算子の二つに兼用される'-'ちゃんは、ちょと可哀想。
部分適用がない言語では問題にもならないが。

>>147
> 関数型言語やるならラムダ計算とかの勉強もしたほうがいいのか?

いいかどうかは分からないが、関数型言語面白い人は面白いと思うが。
http://www.amazon.co.jp/exec/obidos/ASIN/4320023773/t/249-4845079-9009138
あたりだとprogramming言語よりで面白いんじゃないかな。
純粋型なしλ式での負の数の表現も載ってるよ。

>>153
> ついでにトライポッドは広告ウインドウがウザイのぉ。

Javascript off or w3mだから、tripodが広告window出すって知らなかった…
今"page source"して始めて知った。mmmの人はいるのかな?

155 :デフォルトの名無しさん:2001/08/08(水) 00:40
演算子って再定義できなかったっけ?

156 :デフォルトの名無しさん:2001/08/08(水) 00:41
>>151 flipつかえばいいやんけ! って思ったら
subtractの定義はそうなってた。hugsの場合。

157 :石敢當:2001/08/08(水) 16:39
工科大の最後の講義に、整数リストの各要素の4乗の和を求めるコードが
載っています。
http://www.teu.ac.jp/kougi/koshida/Prog6/text13.html より:

sumFourthPowers n = sum (map (^4) [1 .. n])

これの計算過程の説明もありまして、それによると頭から順に4乗を
計算してsumに送り込んでいるようで、ともかく、[1,16,81,...]
という中間リストは生成されないのだそうです。>>122
「Haskellは最外簡約法だから…」と書かれているのはこのことを
さしていたのでしょうか。

そうしますと、>>119で私が書いたfunc2の例でも中間リストなどは
生成されず、効率良く処理されるのかもしれません。

なかなか奥が深いものです。

158 :デフォルトの名無しさん:2001/08/10(金) 02:41
日本語通る?

159 :無名λ式:2001/08/10(金) 03:19
putStrなどは、8bit through。しかしただそれだけ。

ocaml(http://www.ocaml.org)は日本語化されたものがあります。
Web browser, MMMも日本語化されていました。
http://caml.inria.fr/archives/200005/msg00082.html

160 :デフォルトの名無しさん:2001/08/10(金) 18:20
どうも状態ベースで考えてしまう。
えらいこっちゃ

161 :日曜 Haskeller オヤジ:2001/08/11(土) 20:52
結構はげしいのお、東工大の授業は。

Haskell 始めてやっと一週間だが、わしは自分のことをけして
トーシロとはおもっとらんが、内容キツイ。
「リストを扱うプログラム (2)プログラムに対する推論」
まで、やっとたどりついたが、かなり息切れ気味じゃよ。
証明のコツなかなかつかめん、これは数日ではムリだ、
今週の課題になってしもうた。

基底=公理みたいなもんかい?
置換でゴリゴリ押していって、同一になる手順を探し出せっちゅう
ことなんだろうけど、黄金パターンみたいなのはそう簡単には
できそうになさそうじゃ。
むずかしいのぉ。
他にも勉強せんにゃならんもん多かろうに、学生はがんばるのぉ。

162 :デフォルトの名無しさん:2001/08/11(土) 22:56
>>599
でも、THashedStringListって、なんでClassesじゃないのかな?
IniFilesユニットなんかに入れないでほしかった。
あと、TColorBoxって色が漢字で表示できるよね。
その色の漢字("黒"とか"赤")が配列に直接書いてあったよ。
別に使わないからいいけど。

163 :デフォルトの名無しさん:2001/08/11(土) 23:00
>>161
> 基底=公理みたいなもんかい?

基底式は、自然数上の帰納法だとn=0の式、
リスト上の帰納法だとn=[]の式、のような奴らの事。
数学的帰納法の終端になるから、基底。

難しい漢字使っているけど、要するにbase。難しく考える事ない。

この週は数学的帰納法の証明があるから、慣れないと難しいかもね。
けど、慣れればなんて事ないと思う。

text07は関数型言語版design patternですね。

164 :デフォルトの名無しさん:2001/08/11(土) 23:02
普通、東工大っつーと東京工業大学の事。
話題のページは東京工科大学にある。

165 :デフォルトの名無しさん:2001/08/11(土) 23:21
東京工業大学はめちゃくちゃ頭のいい大学として有名。
東大京大の次ぐらいかな。

166 :デフォルトの名無しさん:2001/08/12(日) 00:12
学歴板へカエレ!

167 :デフォルトの名無しさん:2001/08/12(日) 02:59
間違いを指摘しただけでしょ。

168 :石敢當:2001/08/13(月) 16:33
SOE本のExercise 9.9より

「関数fixを、fix f = f (fix f) と定義した場合、fix の型は何か?」

fix fの型をaとするとfの型が a -> a となるので、fixの型が
(a -> a) -> a であることはすぐに分かります。これはいいのですが、
ではこの fix という関数は一体何を意味しているのか、これが
どうも分かりません。

実はこのExerciseには続きがあります。

>remainder :: Integer -> Integer -> Integer
>remainder a b = if a < b then a
> else remainder (a - b) b

これはaをbで割ったときの余りを求める簡単な関数ですが、
このように定義された関数 remainder を関数 fix を使って再帰的でない
ものに書き換えよ、という設問です。

色々考えてはみたものの、答えを得るには至りませんでした。
設問には "tricky!" と書かれているので、ウラ技的なことを
しないといけないのかもしれません。

169 :司馬乱:2001/08/14(火) 00:47
>>168
トリッキーというよりは不動点による再帰の理論的意味づけを
そのままプログラムとして書くとどうなるかという話ですね.

fixは関数を引数に取りその関数の不動点(fixed point)を返す関数です.
ある値xがfの不動点であるとはf xの値が元のxであるということです.
fix f = f (fix f)ですからfix fはfの不動点になっています.

するとこれを利用して再帰的に定義される関数を直接定義することができます.
例として次の再帰的関数を考えましょう.
remainder a b = if a < b then a else remainder (a - b) b
このときまずfを次のような関数とします.
f = \g -> (\a -> (\b -> if a < b then a else g (a - b) b))
remainderの定義のremainderのところを変数gに置き換えたような
形をしていますね.この関数の型は
(Integer -> Integer -> Integer) -> (Integer -> Integer -> Integer)
です.これにfixを適用してやります.するとこの場合fix fの型は
Integer -> Integer -> Integer
となります.このfix fがremainderに対応する関数です.
例で試してみましょう.

(fix f) 12 5
-> (f (fix f)) 12 5
-> if 12 < 5 then 12 else (fix f) (12 - 5) 5
-> (fix f) 7 5
-> (f (fix f)) 7 5
-> if 7 < 5 then 7 else (fix f) (7 - 5) 5
-> (fix f) 2 5
-> (f (fix f)) 2 5
-> if 2 < 5 then 2 else (fix f) (2 - 5) 5
-> 2

もう少し詳しいことを言うと一般には関数の不動点は一つとは限りません.
ここで述べているのはその中で「情報量が最小」なものを
選んでいることに当たります.
つまり普通の再帰的定義で計算される情報だけを返し
それ以上の情報をもたらさないような関数を
不動点として選んでいるということです.
このあたりの正確な議論が知りたい人は関数型言語のスレで挙がっていたような
プログラム言語の意味論のテキストを参考にしてください.

170 :石敢當:2001/08/14(火) 11:45
>>169
早速ご助言を頂きありがとうございます。
fixが不動点を返す関数であること、fix f で余りの計算ができる
ことなどは分かりました。分かったような気がしているだけかも
しれません。
大変勉強になりました。

「情報量が最小」の意味など、分からないこともありますが、
意味論のテキストなどを調べて勉強してみたいと思います。

171 :デフォルトの名無しさん:2001/08/14(火) 12:50
素数の無限リストを効率よく作れます?
自分はいくら考えても激しく遅いのしか思いつかない…。

172 :171:2001/08/14(火) 15:17
http://www.teu.ac.jp/kougi/koshida/Prog6/text13.html
ここにあったや……

173 :石敢當:2001/08/15(水) 22:30
実は、>>169の「関数の不動点を返す」という箇所を読んだとき、
例えば、

>f :: Int -> Int
>f x = 2 * x - 1

と定義すると fix f が 1 を返すのかと(ちょっとだけ)期待して
しまいました。これはうまくいかないですね。これがうまくいく
ということは、

>x = 2 * x - 1

とやったら x = 1 が得られるというのと同じことですものね。

>プログラム言語の意味論のテキストを参考にしてください.

図書館へ行って「プログラミング言語理論への招待」という本を
借りてきました。副題が「正しいソフトウェアを書くために」と
なっています。「再帰の数学」という章があって、ここでは
かなりのページをさいて関数の不動点について説明されています。
「最小の不動点」という節もありますが、これが>>169に書かれて
いる「情報量が最小」ということなのでしょうか。じっくり読んで
みようと思います。

この手の本を読むのは全然嫌いじゃない、というか結構好きですが、
このような理論を理解してからでないとHaskellの「良い」プログラムが
書けないのだとしたら、やはりHaskellはちょっと敷居の高い言語
なのかな、という気もしました。

174 :デフォルトの名無しさん:2001/08/16(木) 00:04
>>173
その本は関数プログラミングとは少しだけ、ずれてない?
たしかに重複する部分もたくさんあると思うけど。
EiffelとHaskellって全然違うし。

175 :司馬乱:2001/08/16(木) 00:09
>>173
お盆でも図書館が開いているのですね.
そうです,最小不動点のことです.
その本なら多分きちんと書いてあるでしょう.

まあ,不動点を使ったプログラミングは
実用的なプログラムでは絶対必要な知識というわけでもないと思います.
上の例ではfixを定義するのにそもそも再帰を使っているのだし,
再帰で書けるのなら再帰を使えばよいだけのこと.
それよりもHaskellならモナドを理解するほうが大事でしょう.

言語設計としてはたとえ理論的には複雑でも
それを知らなくても良いプログラムが書けることがとても大切だと思います.
例えばC++のI/Oストリームなんて型はかなり複雑ですが
それを意識しなくても書けますからね.
この意味でHaskellのモナドはもう少し工夫の余地があると思います.
あれこそ理論を知っているほうが「良い」プログラムが書ける
という言語設計じゃないかな.
関数A->BをA->m(B)と考えるのが計算のモナドの本質であることは
言語仕様からは中々理解しづらいのでは.

176 :司馬乱:2001/08/16(木) 00:15
>>173,174
あ,本を間違えていました.岩波の二分冊の本のつもりでした.
174さんのおっしゃるように
Mayerさんの本ならば関数型にかぎらずいろいろなトピックがあった
ように思いますが,最小不動点の基本的な部分は
多分使えるのではないかと思います(手元にないのでわかりませんが).

177 :デフォルトの名無しさん:2001/08/16(木) 05:03
>「プログラミング言語理論への招待」という本を
昔買っちゃったけど、あの本の内容、サパーリわからんかった。

178 :◆qN5Gq/7Q:2001/08/17(金) 07:44
age

179 :失業おやじ:2001/08/17(金) 19:22
皆さん、勉強してますな。
小生もラムダ計算とやらを勉強するために、
「岩波ソフトウエア講座12 計算理論の基礎理論 井田哲雄著」
を古本屋でゲット。
ほとんど数学のお勉強になってきた。

そう言えば、数式ソフトのマスマテカって関数言語だよね?

180 :失業おやじ:2001/08/17(金) 19:25
>>179
自己レス。本の名前間違えた。
(誤)計算理論の基礎理論
(正)計算モデルの基礎理論

181 :デフォルトの名無しさん:2001/08/17(金) 19:59
マセマティカ

182 :デフォルトの名無しさん:2001/08/17(金) 19:59
>>179-180
その本をうちの研究室のM2の人が読んでますが、教官は「肝心のところで
あやふやな部分がある」と憤慨してました。M2の人は「わかりやすい」と言ってました。
私自身はまだその本を読んではいないのですが、
「数理情報学入門 ― スコット・プログラム理論」中島玲二著 朝倉書店
「プログラム言語の基礎理論」大堀淳著 情報数学講座9 共立出版
を読み始めたところです。
「プログラム言語…」の方は大型書店にいけば売ってますね。

183 :司馬乱:2001/08/18(土) 01:17
なんだか関数型言語のスレに以前あったような話になってきましたね.

>>182
> その本をうちの研究室のM2の人が読んでますが、教官は「肝心のところで
> あやふやな部分がある」と憤慨してました。M2の人は「わかりやすい」と言ってました。

あの本はたぶんオムニバス的に眺めるという趣旨で書かれた本なのでしょう.
あまり数学的にきちんと突き詰めて理解するようには書かれていなかったと思います.
(中身を見たのがだいぶ前なのであやふやですが).
その教官は理論をちゃんとやってきた人なのでしょう.

> 「数理情報学入門 ― スコット・プログラム理論」中島玲二著 朝倉書店
> 「プログラム言語の基礎理論」大堀淳著 情報数学講座9 共立出版

これらはきちんと書かれています.が,その分とっつきにくいかもしれません.
理論を研究で使うならこれらをしっかり読むのはとても良いことだと思います.
ぜひぜひがんばってくださいな.
つーか,182さんがどの辺の人かわかってしまいそう.

それから言うまでもありませんが
Haskellプログラミングそのものにはこういう話は別に必要ありません.>all
むしろプログラミングが得意な人にはがんがん環境を整備して欲しい.
今どきのプログラミングは充実したライブラリがないと中々難しいし.
やっぱりHaskell.NETに期待か?

184 :デフォルトの名無しさん:2001/08/18(土) 01:35
そういや、Haskell.NETあったな。
すっかり忘れてたが、笑える。

185 :司馬乱:2001/08/18(土) 02:34
>>184
いや,Peyton-JonesがいるからMSRではやるんじゃない?
それに趣味で実装する分には面白そうかも,とちょっと思ったり.
.NET関係のきちんとした仕様書って手に入るのかな?
Linuxとかでやってる人はどうしてるんだろう?

186 :デフォルトの名無しさん:2001/08/18(土) 16:24
このスレって.NETとか、そっち方面には疎い人多そう。

187 :日曜 Haskeller オヤジ:2001/08/19(日) 07:49
ふぅ、徹夜してしまった。
でも、だいぶん証明にもこなれて来ました。
http://www.teu.ac.jp/kougi/koshida/Prog6/text06.html
をやっと突破できました。

コツは

1.証明が必要なものと、証明不要なものをしっかりと分類して整理する。
2.帰納するときの直前直後の要素を混同しないよう、記号をはっきりと意識する。
 要するに、証明すべき P(xs) -> P(x:xs) の xs および x:xs に注目する。
3.証明の最初は、帰納法の仮定 hyp 目指して置換してゆく。

ちゅう事なんですね。

今週の成果です。

勘違いは、ないでしょうか?
暇な方いらっしゃいましたら添削お願いします。
記号は私の好みで勝手に変えてしまいました。

全ての有限リスト a ,b 及び c に対し次の式を証明せよ
a ++ [] == a                 (++3)
a ++ (b ++ c) == (a ++ b) ++ c        (++4)

-------------------
(++) の定義
[] ++ ys == ys                (++1)
(x:xs) ++ ys == x:(xs ++ ys)         (++2)

-------------------
(++3)の証明
 [] ++ [] == []               (base:要証明)
 (ah:at) ++ [] == (ah:at)          (ind:要証明)
 at ++ [] == at               (hyp:証明不要)

 ------------------
 (base:要証明)の証明
 [] ++ [] = []
 [] == []                  (++3)
 証明終わり

 ------------------
 (ind:要証明)の証明
 (ah:at) ++ [] == (ah:at)
 ah:(at ++ []) == (ah:at)          (++2)
 ah:at == (ah:at)              (hyp:証明不要)
 証明終わり

(base:要証明)および(ind:証明不要)より
a ++ [] == a
証明終わり

188 :日曜:2001/08/19(日) 07:50
-------------------
(++4)の証明
 [] ++ (b ++ c) == ([] ++ b) ++ c      (base:要証明)
 ah:at ++ (b ++ c) == (ah:at ++ b) ++ c   (ind:要証明)
 at ++ (b ++ c) == (at ++ b) ++ c      (hyp:証明不要)

 ------------------
 (base:要証明)の証明
 [] ++ (b ++ c) == ([] ++ b) ++ c
 b ++ c == b ++ c              (++1)*2
 証明終わり

 ------------------
 (ind:要証明)の証明
 ah:at ++ (b ++ c) == (ah:at ++ b) ++ c
 ah:(at ++ (b ++ c)) == (ah:at ++ b) ++ c  (++2)
 ah:(at ++ (b ++ c)) == ah:(at ++ b) ++ c  (++2)
 ah:((at ++ b) ++ c) == ah:(at ++ b) ++ c  (hyp:証明不要)
 ah:((at ++ b) ++ c) == ah:((at ++ b) ++ c) (++2)
 証明終わり

(base:要証明)および(ind:証明不要)より
a ++ (b ++ c) == (a ++ b) ++ c
証明終わり

ところで、ここの課題2の問題
sum (xs ++ ys) = sum xs ++ sum ys
は、
sum (xs ++ ys) = sum xs + sum ys
の誤植かと思われますが、先生はこのスレッドを見ていらっしゃいますでしょうか?

さて、来週は楽になるかのぉ

189 :石敢當:2001/08/20(月) 14:06
>>187, >>188
>暇な方いらっしゃいましたら添削お願いします。
あんまり暇じゃないですが…

>(ind:要証明)の証明
>(ah:at) ++ [] == (ah:at)

A = B の証明をするのに、A = B から書き出すのは良い書き方では
ないと思います。普通は
  A = ...変形をしてゆくと... = B、 よってOK、
とか
  A = ...変形すると... = X, B = ...変形すると... = X、
よってA = Bなどと書くのが一般的と思います。

内容は間違っていないように思います。

190 :石敢當:2001/08/20(月) 14:07
http://www.teu.ac.jp/kougi/koshida/Prog6/text06.html 課題1にある
「シーケンス」という言葉を見て思い出しました。

http://www.teu.ac.jp/kougi/koshida/Prog6/Text12/index.html
ここの問題2です。

リストの全サブリストを返す subLists という関数、
リストの全サブシーケンスを subSequences という関数を定義せよ、
という問題です。

subLists は簡単で、与えられたリストを x:xs とすると、xsの
サブリストを再帰的に求め、各々の要素に x を含むものとそうでない
ものを考えれば良いので、例えば次のように定義できます。

>subLists (x:xs) = [e | ys <- subLists xs, e <- [x:ys, ys]]

subSequences の要素は、元のリストの先頭または末尾からそれぞれ
連続した任意個の要素を省いたものなので、
  sub1 [x1,x2, .. ,xn] = [[x1, .. ,xn],[x2, .. ,xn], .. ,[xn]]
  sub2 [x1,x2, .. ,xn] = [[x1, .. ,xn],[x1, .. ,x(n-1)], .. ,[x1]]
となるような関数を定義してなんとか作ることはできましたが、
もっとすっきりできないかと思案中です。subLists 程度の簡単な
関数を作れると良いのですが…。

191 :デフォルトの名無しさん:2001/08/20(月) 22:49
>>190
石敢當さんの言ってるのだと
subSequences [1,2,3,4] =>
[[1],[1,2],[1,2,3],[1,2,3,4],[2,3,4],[3,4],[4]] -- []も入るのかな?
のようになるような感じですが
問題のほうを読むと、[2,3]も入ってないといけないような気が…。

192 :石敢當:2001/08/20(月) 23:15
>>191
[1,2,3,4]の場合ですと、
sub1 [1,2,3,4] = [[1,2,3,4],[2,3,4],[3,4],[4]]
となり、この各々に sub2 を適用して、
sub2 [1,2,3,4] = [[1,2,3,4],[1,2,3],[1,2],[1]]
sub2 [2,3,4] = [[2,3,4],[2,3],[2]]
sub2 [3,4] = [[3,4],[3]]
sub2 [4] = [[4]]
となる、という意味で書きました。sub1, sub2 を使って定義すると、

subSequences xs = [zs | ys <- sub1 xs, zs <- sub2 ys]

となります。この定義では [] が出てこないので、[] も
サブシーケンスとみなすのであれば [] を追加する必要があります。

あまり長くならないようにしようと多少端折って書いたので
分かりにくかったかもしれません。

193 :191:2001/08/20(月) 23:26
>>192
なるほど!
なんか、十分すっきりしてるように見えます…。

194 :日曜Haskellerオヤジ:2001/08/20(月) 23:52
>>189
お忙しいところ、どうもありがとう御座います。
早速、勘違いとか問題点とか見つかったので良かったです。
なにを勘違いしていたかというと、方程式を解くようなイメージを持っていたということで、こんなことやってしまってました。

http://www.teu.ac.jp/kougi/koshida/Prog6/text06.html の課題2の証明中
 ah + (sum at ++ b) == ah + (sum at) + sum b  (sum2)
 (sum at ++ b) == (sum at) + sum b       (-ah)
 sum at + sum b == (sum at) + sum b       (ind:証明不要)
二行目のところ、両辺から ah を引いてますが、
こりゃマズイってことに気付きました、これが許されるなら0掛けたらどうなる!!
あと、関数の定義で a x = b の時 b = a x と考えて置換、これも多分マズイですよね?
a x が b であっても、b であれば a x とは限らないですよね?
反例が浮かばない・・・
あくまでも同等であるということを意識しないといけないですね。

コツ+1
1.証明が必要なものと、証明不要なものをしっかりと分類して整理する。
2.帰納するときの直前直後の要素を混同しないよう、記号をはっきりと意識する。
 要するに、証明すべき P(xs) -> P(x:xs) の xs および x:xs に注目する。
3.証明の最初は、帰納法の仮定 hyp 目指して置換してゆく。
4.左辺=右辺を証明するとき、左辺の変形と右辺の変形はしっかり区別しておく事。
 そのためには、式を混ぜずに別々にやるべきである。
 両辺を変形するのはゴール地点を増やして、道しるべを作っておくことである。

Haskellといいますか、プログラムの証明をやると、
自分のやってた算数がいかにいい加減だったかよくわかる。(^^;

195 :日曜Haskellerオヤジ:2001/08/20(月) 23:52
ところでやってしまった例の2行目なんですが、少なくともこの場合は上手いきます。
しかも便利はいいので(特に長いプログラムでは)、そこで問題点を洗い出して使えるようにしてみようと思ってる訳ですが・・・

例えば足し算の時、
 ((+) 整数 整数)
 ((+) 未定義 整数)
の全部で2パターンがあると思います(まだあるのか?)

この時
a == b ⇔ ((+) a c) == ((+) b c)  (c は必ず整数です)
となれば良いのではなかろうかと考えてみました。
a b が共に整数なら自明、それ以外でも、未定義を加算した結果も未定義
一般的には a == b ⇔ f a == f b の時、両辺を置換してしまえる・・・のかな?
大丈夫ですかね?

>>190
美しく書かれた、汎用の語彙スキャナは確かに最初に欲しいですね。
私も多分 Haskell を憶えたら、まっ最初に作ると思います。
ちなみに現在「オーバーロードとクラス」にアタック中です。

196 :日曜Haskellerオヤジ:2001/08/21(火) 00:06
>>195
あっ、スキャナじゃなかった、サブリストだ、失礼しました。

197 :無名λ式:2001/08/21(火) 00:12
> この手の本を読むのは全然嫌いじゃない、というか結構好きですが、
> このような理論を理解してからでないとHaskellの「良い」プログラムが
> 書けないのだとしたら、やはりHaskellはちょっと敷居の高い言語
> なのかな、という気もしました。

全然必要じゃねー。

最小不動点にしても、スコット理論にしても、
プログラムの意味を数学的な構造と関連付けて理解するという
表示的意味論の世界であって、programmingそのものには関係ない。
ただ、「継続」を理解すれば、モナドは楽勝かも。
>>182
> 「数理情報学入門 ― スコット・プログラム理論」中島玲二著 朝倉書店
には、「継続」がごく簡単に説明されていたと記憶する。
多値の中の一つとして継続(の一部)を直接扱うためにliftしたというだけの話なので。

198 :石敢當:2001/08/21(火) 11:14
>>193
sub2 の定義がどうもすっきりしてないように見えるんです。
リストの末尾の方から要素を省いていくって面倒ですよね。

>>197
>全然必要じゃねー。

そう言われると多少気が楽になります。
でもまあ、理屈の話も面白いのでそれなりに…。

>ただ、「継続」を理解すれば、モナドは楽勝かも。

この「モナドは楽勝かも」という言葉には惹かれますが、
調べてみたら、最寄の図書館にはこの本がなかったのが残念です。

199 :デフォルトの名無しさん:2001/08/21(火) 12:24
>>197
そこでいう「継続」って Scheme のやつと同じもの?

200 :無名λ式:2001/08/21(火) 12:46
表示的意味論の「継続」は「全」状態の1 snapshotを表している。

これがschemeのccの由来。Lisp programmingに有用なものだけ抜き出してある。
だからcall/ccしても大域変数の値がbacktrackしたりはしない。
機能はスタックがスタックフレームのリストだったInterlispにinspireされたと思う。
用語や意味づけは表示的意味論から持ってきた模様。

201 :デフォルトの名無しさん:2001/08/21(火) 16:36
「モナドとかいっても結局状態を扱ってるんだろ」という極論は、
「オブジェクト指向とかいっても結局変数とサブルーチンなんだろ」
という極論と似ていると思った。

202 :デフォルトの名無しさん:2001/08/21(火) 17:18
>>201
いやむしろ、状態を扱わないようにするのがモナドだと思ってるのが勘違いでは?

203 :デフォルトの名無しさん:2001/08/22(水) 14:31
{-

204 :201:2001/08/22(水) 16:12
そうだね。間違えた。

205 :デフォルトの名無しさん:2001/08/22(水) 16:15
終わりを忘れずに♪
-}

206 :デフォルトの名無しさん:2001/08/23(木) 05:02
実用プログラムとして、無限リストのルンゲ・クッタ法を
実現しようかなと考えているものの、まだ未着手(wara

207 :失業おやじ:2001/08/23(木) 08:53
ラムダ式をHaskellで表現したいのだが、うまくいかない。

ラムダ式は
<<λ項>> ::= <<変数>> | <<λ項>><<λ項>> | λ<<変数>>.<<λ項>>
と表現できるらしいが、
これをHaskellのデータ型で定義したいのだが、なかなかうまく
いかない。だれか教えて。

208 :日曜Haskellerオヤジ:2001/08/23(木) 11:28
わしもついでに質問します。
http://www.teu.ac.jp/kougi/koshida/Prog6/text09.html
の問題1やっているところです。

どうしても上手くいかなくて、テストのもっと簡単なのをつくって見ますと・・・
同じ書き方なのに、なぜオーバーロード関数を見つけない?
という問題に出くわしました。

class Visible a where
 xshow :: a -> String

instance Visible Char where
 xshow a = "test-char"

instance Visible Int where
 xshow a = "test-int"

xshow 'a' とすれば、上手く "test-char" と表示されるんですが。

xshow 1 とすると・・・

ERROR - Unresolved overloading
*** Type : (Num a, Visible a) => [Char]
*** Expression : xshow 1

とメッセージ出します、なんででしょ?

209 :デフォルトの名無しさん:2001/08/23(木) 11:38
type Var = String
data Term = Var Var | Aplly Term Term | Lambda Var Term
deriving (Eq, Read, Show)

210 :デフォルトの名無しさん:2001/08/23(木) 13:20
Haskellはなんと読みますか。

ハスケル
ハズケル
アスケル
ハースケル
アシュケル
アシュカル
ハスキル

211 :デフォルトの名無しさん:2001/08/23(木) 13:40
ガッコで教わったときは、先生はハスケルと読んでたよ。

212 :デフォルトの名無しさん:2001/08/23(木) 15:02
>>208 確か 1 は Intではないため。
1 :: Num a => a だな。
Visible (1::Int) ってやればとりあえずエラーは出ないのでは。
もしくは
instance Num a => Visible a
xshow a = 'test-num'
だと動作が違っちゃうね。

213 :デフォルトの名無しさん:2001/08/23(木) 15:16
http://www.score.is.tsukuba.ac.jp/~minamide/lectures/compiler.htm

214 :デフォルトの名無しさん:2001/08/23(木) 17:44
簡単なコンパイラでも作ってみようかな?
Pascalあたり簡単そうだね。
けど、ただのお遊びで終わる感が…

215 :失業おやじ:2001/08/23(木) 18:53
>>209 さん、どうも。

ためしに、以下のように入力するといずれもエラーとなるのだが?

Aplly "x" "y"
Aplly (Var "x") (Var "y")
Lambda "x" "y"
Lambda "x" (Var "y")

216 :デフォルトの名無しさん:2001/08/23(木) 20:30
>>215
2番目と4番目はエラーにならないのだが?

217 :失業おやじ:2001/08/23(木) 22:22
>>216
やはり、Hugs98ではエラーとなるなあ。どうしてかな。

「計算モデルの基礎理論」を読んでて、λ式の変形、簡約って
けっこう面倒なので、Haskellでλ式処理できればいいなと
思って。

218 :216:2001/08/23(木) 22:50
>>217
こっちもHugs98(win)なんだが…。

>>209の deriving (Eq, Read, Show) をインデントしてるよね?

うーん…

219 :失業おやじ:2001/08/24(金) 00:45
>>218
>deriving (Eq, Read, Show) をインデントしてるよね?
Tab入れたら動いた。>>209 をそのままコピーしたので、
オフサイドしてたわけね。

data Term = Var Var の Varを2個並べるのって変な感じ。
前者のVarはデータコンストラクターで後者はStringを意味
するんだよね。すっきりしない。

220 :石敢當:2001/08/24(金) 00:56
>>190
以前に書いたサブシーケンスの問題、多少簡潔に書けました。
(前回のsub1, sub2を使ったものは10行以上ありました)

>subseq :: [a] -> [([a], Bool)]
>subseq [] = [([],True)]
>subseq (x:xs) =
> [(x:ys, True) | (ys, flag) <- yss, flag || null ys] ++
> [(ys, False) | (ys, flag) <- yss]
> where yss = subseq xs

x:xs のサブシーケンスを求めるのに xs のサブシーケンスを
使っています。ys を xs のサブシーケンスとするとき、x:ys も
サブシーケンスになるには、ys が xs の先頭要素から始まって
いるか、ys が [] である場合だけです。前者の条件を満たす
場合に flag = True となるような、サブシーケンスとフラグの対
からなるリストを生成しています。

subSequences は subseq の結果からフラグを取り除けはOKです。

>subSequences :: [a] -> [[a]]
>subSequences = map fst . subseq

221 :デフォルトの名無しさん:2001/08/24(金) 02:07
>>220
あまりエレガントな感じしないなぁ。
sub1, sub2 が長いのがいやなら、既存のものを使うとか。

import List
subSequences xs = nub [zs | ys <- tails xs, zs <- inits ys]
-- nub で消してるのは [] だけよ。

222 :司馬乱:2001/08/24(金) 02:41
>>197
> ただ、「継続」を理解すれば、モナドは楽勝かも。

どちらかというと逆で,具体的にどう書くかは別にして,
モナドを使うと一種の継続を表現することができます.
えーと,Rを仮想的な結果の型として
関数A->BをA->((B->R)->R)と見なすようにモナドを定義します.
このときB->Rが型Bの継続の型です.
また,これは状態遷移のモナドとはちょっと違うことに注意してください.
こちらはSを状態の型として関数A->BをA->(S->(B,S))と見なすように定義します.
これはAとSを同時に引数にとると考えると(この変換を非カリー化といいます)
(A,S)->(B,S)となるので状態がくっついている様子がよくわかります.

繰り返しておくと,上の定式化を比較すればわかるように
関数A->BをA->M(B)と見なすということが計算のモナドの基本的アイデアであり
状態遷移はその適用例の一つに過ぎません.
もともと表示的意味論を整理してモジュール化するというのが
意味論にモナドを持ち込んだ目的の一つでしたので,このメカニズムにより
状態や継続などを表現することは最初から考えられていました.

>>200
> 用語や意味づけは表示的意味論から持ってきた模様。

というかSchemeの仕様書の最後の方に表示的意味論使って書いてあるんじゃない?

223 :デフォルトの名無しさん:2001/08/24(金) 09:27
http://www.teu.ac.jp/kougi/koshida/Prog6/Text03/index.html
ここの課題2って、こういう感じでいいのでしょうか。
もっと単純にかけそうな気がするというか、
エレガントに書けそうな気がするんですが。

maxOcc :: Int->Int->(Int,Int)
maxOcc a b
| a>b =(a,1)
| a<b =(b,1)
| a==b=(a,2)


maxThreeAux :: Int->(Int,Int)->(Int,Int)
maxThreeAux a (b c)
| a == b =(b c+1)
| a >b =(a 1)
| b <a =(b 1)


maxOcc3 :: Int->Int->Int->(Int,Int)
maxOcc3 a b c =maxThreeAux a (maxOcc b c)

224 :石敢當:2001/08/24(金) 10:27
>>221
>あまりエレガントな感じしないなぁ。

しないですね〜(笑)。特にフラグってのが良くないです。
subSequences xs の結果を直接的に使ってみたかっただけなんですが、
スマートにやるのは難しいです。

225 :日曜Haskellerオヤジ:2001/08/24(金) 16:58
>>212
どうもです、
1 というのは Int 型ではないのか・・・
確かに、文法考えると Float なのか Int なのか区別つかないから適当に推定しないといけないですからね。
Haskell はこの推定部分をプログラムできるような構造をもっているということなんでしょうか。
とりあえず (1::Int) として指定すれば、良いみたいですね。
なんとかしてやろうと思って、他の関数はどうなってるのか
Prelude.hs を見てみましたら、謎のキーワードの山でひっくりかえってしまいました。

>>223
私もそうしてしまいました、基本は全部列挙、内容が自明で個数が数行で
書ききれるならば、条件別に全て書いてしまうべきだという
変なポリシーあったりしますので。
そういったものが沢山あるとき、一旦一般化した関数を作ってそれを使うのが
もっとも良いのではと思います。

226 :デフォルトの名無しさん:2001/08/25(土) 10:38
λ演算てなんですか。ハスケル用語ですか。

ハスケルってケミカルに似てますね。

227 :失業おやじ:2001/08/25(土) 14:03
このスレでだれかが紹介していた「ラムダ演算のABC」
>http://members.tripod.co.jp/nbz/ref/lambda.html

228 :日曜Haskellerオヤジ:01/08/26 23:59 ID:RJYyeZQc
http://www.teu.ac.jp/kougi/koshida/Prog6/Text11/index.html の問題3
をやっております。

とりあえず作ってみたが、もっと格好のよい例はないもんかのぉ
なかなかええのができん、もっと良い方法で解かれた方はおりませんか?

とりあえず、格好の良い関数の条件
1.(+) を新しく作ったりしない事。
2.エラーは maybe 一丁で全部処理する、maybe もどきは作らない。

-- 一番最初に考えた格好の悪い例
-- 問題点は maybe 関数が引数を一つしか取らないのが問題かと思い
-- 引数をまとめてしまうことを考えてみた、・・・しかし
-- そもそもグループ化する意味がないのが悲しい
-- 伝播する意味がない、どちらかが Nothing と判明した時点
-- で 0 で終了が確定するわけで・・・
-- 使いどころを探して無理やり maybe を使ってみましたという
-- 強引さが否めない。
-- さらには (+) を新たに起こしている時点で死刑
grp :: Maybe a -> Maybe a -> Maybe (a,a)
grp (Just a) (Just b) = Just (a,b)
grp _ _ = Nothing

process :: [Int] -> Int -> Int -> Int
process l a b = r
 where
 p = errPos l
 ab = grp (p a) (p b)
 add = (\(a,b) -> a + b)
 r = maybe 0 add ab

おまけ
-- とりあえず素直な形の物を作ろうと考えた例
-- maybe は使いませんでした
-- 直感とマッチする、まだ上の例より良い印象がする。
process :: [Int] -> Int -> Int -> Int
process l a b = r
 where
 add (Just x) (Just y) = x + y
 add _ _ = 0
 p = errPos l
 r = add (p a) (p b)

229 :デフォルトの名無しさん:01/08/27 00:12 ID:1KI/GxRs
なんか楽しそうな言語だな。
ソース見ても何やってるかさっぱり分からん。

Windows用のインタプリタ拾ってきたんで遊ぼうかな。

230 :デフォルトの名無しさん:01/08/27 11:03 ID:QgN1dslo
とりあえず関数型言語の基礎を固めよう、ってわけで、
「関数プログラミング(R.ワード、P.ワドラー共著)」
という本を買ってきました。
まだはじめしか読んでいませんが、
文法が非常にHaskell似(というか他の関数型言語似?)なので
とっつきやすいです。

231 :無名λ式:01/08/29 01:43 ID:hol8O3eY
>>222
> > 用語や意味づけは表示的意味論から持ってきた模様。
>
> というかSchemeの仕様書の最後の方に表示的意味論使って書いてあるんじゃない?

そりゃまあみんな知ってるさ…

そもそもActorを実装を通して理解しようとしたのがSchemeの始まりだから、
asynchronous messageを使ったinteractionをLisp上で実装しようとして、
continuationを使うalphaを導入した。

表示的意味論を元に考えた機能というよりも、
必要に迫られた機能をSussmanが表示的意味論で料理した。

と記憶しているけど、どうかな? > 古い人

Haskellあんまり関係ないのでsage

232 :司馬乱:01/08/29 15:36 ID:.1zEHsV.
>> 231
個人に向けたわけでもないので気を悪くしてたらごめんね.
もちろん知っている人は皆知ってますけど,
そもそもよく読んでない人のほうが多いと思うんで.
設計の内部事情についてはよく知らないので古い人おねがい.
ただ当時のMITあたりでは表示的意味論は
相対的に今よりもずっとポピュラーだったと思うよ.

233 :デフォルトの名無しさん:01/08/30 01:04 ID:WVyzjEXQ
>>230
Haskell の構文はこの本で処理系の実装としてとりあげられている
Miranda の構文を元にしているような。リストの内包表記なんかは
Miranda が最初かなあ。

234 :デフォルトの名無しさん:01/08/30 18:45 ID:efSLTqvs
状態モナドを使ったら、参照透過性が崩れてしまうということは
ないんですか?
状態を保持する変数があったら、変数の内容が変わるから
参照透過性が崩れてしまうような気がするのですが。

あと、関数型だと何が便利になるんでしょうか?
やはり参照透過性を確保するためでしょうか?
参照透過性以外の理由で、何か理由があるのでしょうか?

235 :デフォルトの名無しさん:01/08/31 10:40 ID:qFU2ZcoI
>>234
>状態モナドを使ったら、参照透過性が崩れてしまうということはないんですか?

状態モナドは参照透明性を確保しつつ、状態を扱うためのテクニックです。

>参照透過性以外の理由で、何か理由があるのでしょうか?

高階関数による抽象化。

236 :日曜Haskellerオヤジ:01/09/01 02:21 ID:EaZ91DHw
>>190
やっとそこに、たどり着きました
自分の頭で考えたら、
リストの内包表現を使いさえすればよい例って感じになってしまった。

subLists :: [a] -> [[a]]
subLists (ah:[]) = [ [ah] , [] ]
subLists (ah:at) = [ ah:t | t <- (subLists at) ] ++ [ t | t <- (subLists at) ]

subSequences :: [a] ->[[a]]
subSequences (ah:[]) = [[ah]]
subSequences (ah:at) = [ take n (ah:at) | (x,n) <- zip (ah:at) [1..] ] ++ (subSequences at)

なんかただ使ってみたって感じがしますね。
特に subSequences は zip やら take やら、入っていてやな感じ。
もうちょっと考えてみよう。

しかし石敢當さんの subLists は凄いですね。
今日はこれから http://www.teu.ac.jp/kougi/koshida/Prog6/text13.html やります。

237 :石敢當:01/09/01 23:16 ID:rP6jh0SY
>>228
私も作ってみましたが、あんまりすっきりしたものができません
でした。何の制約もなければ簡単に書けるプログラムですが、
「maybe と errPos を使って」という制約がありますので、
Maybe型に慣れるための演習と思うことにして、すっきりした
コードはあきらめました。

>>236
subListsの別定義を考えてみました。構成する方法は以前と同じですが、
要素の並びを変えてあります。

subLists :: [a] -> [[a]]
subLists [] = [[]]
subLists (x:xs) = y : map (x:) (y:ys) ++ ys
where y:ys = subLists xs

以前の定義と比べて何が良いかと言うと、整数型のように
大小を比較できる要素のリストの場合、昇順にソートした
リストを渡すと得られる結果もソートされている点です。

例) subList [1,2,3] = [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]

リストで集合を扱う際などには、このようになっていたほうが都合の
良いときがあります。

238 :デフォルトの名無しさん:01/09/03 17:02 ID:q1FVMZpM
Haskellでファイルの入出力方法がわからんage
この辺がモナドってやつに関係するのかな?

239 :デフォルトの名無しさん:01/09/03 18:48 ID:M/nB86do
>>238
ん?工科大のテキストしか読んでないのか?

http://www.sampou.org/haskell/tutorial-j/index.html
とかも読め。

240 :デフォルトの名無しさん:01/09/04 02:03 ID:RaNfIHXg
>>239
これを読んでモナドわかった人いる?
入出力のやり方ぐらいは見様見真似で出来るようなるけど。

http://www.sampou.org/haskell/tutorial-j/monads.html
の9.3のところでいきなりわからなくなるんだけど、

data SM a = SM (S -> (a,S)) -- The monadic type

これ、両辺にSMが出てきてるよね?
すると、このSMって同じ物を表してるんだよね?
ということは、SM a が SM (S -> (a,S)) と一緒?
ということになると、aが(a,S)を返す関数ってことになって
つまり、自分自身を含む組を返す?
頭がこんがらがってきます。

で、正確にはどう解釈したらいいんだろう?

241 :デフォルトの名無しさん:01/09/04 02:57 ID:NuBIcPiU
>>240
> このSMって同じ物を表してるんだよね?
違います。左辺のSMは型構築子右辺のはデータ構築子。
http://www.sampou.org/haskell/tutorial-j/goodies.html#sect2.2

> で、正確にはどう解釈したらいいんだろう?
SM a という型は S -> (a,S) という型の関数に構築子 SM を適用した型。

モナド以前sage

242 :司馬乱:01/09/04 03:09 ID:AKFDllL2
>>240
http://www.sampou.org/haskell/tutorial-j/goodies.html
の2.2に書いてありますね.最初のSMは型構築子,
次のSMはデータ構築子(データにくっつくタグみたいなもの)です.
名前空間が違うので同じ名前を使えますが別物です.

243 :デフォルトの名無しさん:01/09/04 04:04 ID:fOPLKsP2
241の方が242よりも詳しいのに、242の方が
いい人に見える不思議。

244 :失業おやじ:01/09/04 23:47 ID:AzLGsopo
関数言語って、ちょっと深くやろうとすると難しいね。
写像の連続で意味を追うというのも、疲れるね。
状態の変化を追う方が楽なような気もする。

245 :デフォルトの名無しさん:01/09/05 00:13 ID:36o5GiFQ
どんなプログラムを作るのに向いてるの?

246 :デフォルトの名無しさん:01/09/05 00:40 ID:a3PLHGJI
自分で考えなさい。(1問20点)

247 :日曜Haskellerオヤジ:01/09/05 00:44 ID:YYUBVOJs
>>245
まだやり始めて短いですが、現状見た感じですと・・・趣味ですね。(^^;
あと、他言語でのプログラミングスタイルの強化や修正とか。
プログラムというものの本質をみる言語じゃないかな。
プログラム言語を考えるためのプログラム言語とかどうでしょう。

そうそう、あと無限リストが取扱えるというのは結構衝撃ですよ。
もちろんそれっぽいものは、他言語でもできますが、Haskellは綺麗にやってのけてます。
こんな感じで
a = [x * 2 | x <- [1..] ]
[1..] は 1〜∞ までの自然数のリスト a は 2,4,6〜∞ のリスト
普通の言語だと、こんな書き方するとメモリーが足らない上に停止しない。
このへんが面白いです。

248 :240:01/09/05 01:32 ID:yPl1nwvo
>>241-242
どうもありがとうございます。
左辺と右辺のSMは別物だと捕らえたらなんとか理解できました。

しかし、SMの定義を見てると何か釈然としないものを感じます。
例えば、状態を読み取る時は

runSM s0 readSM

となるんだろうけど、これは(s0,s0)を返すにすぎませんよね?
これでは何の意味があるのだか良く分かりません。
状態を読み取ると言っておきながら、自分で状態を指定してるではない
ですか?また、状態を更新する時なのですが、

runSM s0 (updateSM f)

これは要するに、”前の状態と変化の仕方を引数として、後の状態を返す”
というのと同じことで、普通にそういう関数を作っても全く副作用は
無いと思いますが、なぜモナドにする必要があったのでしょうか?
あと、モナドを返す文と新たな文をくっつけて、またモナドを返すように
するというように、”>>や>>=やreturnを使って、モナドを返す部分を
どんどん伝染させていってる”ように感じるのですが、これは何のために
やってるんでしょうか?

あとは、getCharでちょっとした疑問があるのですが、getCharは場合によって
IO 'a'を返したり IO 'b'を返したりするはずです。これは参照透明性を失って
いるようにみえるけど、なぜ大丈夫なんでしょうか?

249 :デフォルトの名無しさん:01/09/05 02:57 ID:MClHLUZo
HaskellでOOPするにはどうやるんだ?
Haskellにはオブジェクトの内部状態という概念が無いから困るだろう。
モナドを使うのか?

250 :デフォルトの名無しさん:01/09/05 12:44 ID:WemS0OIU
>>245
>どんなプログラムを作るのに向いてるの?

たぶん、抽象度の高いものに向いてるんだろう。
記号処理とか。
OOPとかは、シュミレーションなどの実際のデータ
変化を伴うものは書きやすいが、記号処理なんか
はOOPで書くの大変だろう。

251 :デフォルトの名無しさん:01/09/05 15:32 ID:Bii0lg4I
でも、これだけオブジェクト指向ありきの世の中になってまで、
オブジェクト指向が出来ないってのは相当な痛手だと思うけど。

252 :デフォルトの名無しさん:01/09/05 16:12 ID:6PT9EWiQ
大学の「情報工学」と名の付く学科を出ていながら、関数型言語やプログラムの基礎理論
のことをなに一つ知らない連中もちょっと問題ありだけどね。

253 :日曜Haskellerオヤジ:01/09/05 16:17 ID:o26RlTLc
>>251
Haskell は、OOPで実装しても意味がないんじゃよ、時間軸が言語から分離消失してるからね。
考えること事態がナンセンスや、それでも OOP とは違うが似た概念はあるで。
class とか instance とか、実装されとる。
だが、実体はOOPとは全くの別物やね。

まあ、詳しいことは一度やってみるとええ。
プロセス型言語とは決定的に違うHaskellの世界で常識をいっぺん引っくり返してみ。
もっともわし、始めて2ヶ月やからトンデモないことぬかしとるかも知れんが・・・(笑)

254 :デフォルトの名無しさん:01/09/05 16:42 ID:6AdS52o2
>>248
「同じ文脈(用語は不安ですが)では、同じ変数は同じ値を表す。」
というのが参照透明性ですが、
getChar は同じ文脈では1度しか出現できないので、参照透明性
が保たれていると言えます。

255 :石敢當:01/09/05 16:55 ID:OAv7PsgU
>>236
>今日はこれから http://www.teu.ac.jp/kougi/koshida/Prog6/text13.html やります。
私も考えてみました。問題2だけ書きます。

2, 3, 5 で順に割ってみて2, 3, 5以外の素因子がないものだけを
拾い出せばokですが、これだととっても時間がかかります。
[2^a * 3^b * 5^c | a <- [0..], b <- [0..], c <- [0..] ]
と書ければ簡単ですが、これだとaとbが永遠に0のままですので細工を
しないといけません。まず、3つ組を順に生成する関数を定義します。

type Triplet = (Int, Int, Int)

nextTriplet :: Triplet -> Triplet
nextTriplet (0, 0, c) = (c + 1, 0, 0)
nextTriplet (a, 0, c) = (a - 1, c + 1, 0)
nextTriplet (a, b, c) = (a, b - 1, c + 1)

triplets :: [Triplet]
triplets = (0,0,0) : [ nextTriplet t | t <- triplets ]

こうすると非負整数から成る全ての3つ組の列 triplets が得られ
ますので、これを用いて

humming2 :: [Integer]
humming2 = [ 2^a * 3^b * 5^c | (a, b, c) <- triplets ]

と定義すれば、順に割っていく方式のものよりははるかに高速です。
(ただし、このリストは小さい順には並んでいないです)

256 :デフォルトの名無しさん:01/09/05 17:26 ID:4nU3LYhU
Haskell の拡張だけど一応
http://www.cs.chalmers.se/~nordland/ohaskell/
http://www.cs.chalmers.se/~rjmh/Software/h++.html

俺は Haskell で OOP なんてしたいと思わないけど。

>>254
俺は、getChar というか IO レベルでは
同じ式でも違う値を返し、参照透過性を保ってないと理解しているのだけど。

でも、IO a 型のデータ構築子は定義されてないので
a の値だけを取り出すことは出来ないため、
IO ってタグが付かない場所では IO を使うことが出来ないので
IO 以外のレベルでは参照透過性は保たれるので大丈夫。
って事だろうと理解している。

間違ってたら訂正きぼん > 識者

257 :デフォルトの名無しさん:01/09/05 17:31 ID:4nU3LYhU
追記。
IO a 型のデータ構築子云々ってのは
IO ってデータ構築子があるのなら
fromIO :: IO a -> a
fromIO (IO x) = x
って書けるって話。

258 :デフォルトの名無しさん:01/09/05 23:31 ID:.VljIIMQ
オブジェクト指向が出来ない言語なら実用性に疑問が残るね。

259 :司馬乱:01/09/06 01:34 ID:FsBmKxpM
OOPとは何ができることか考え直してみればHaskellでもかなりのことはできます.
大まかに言えばOOPの静的な側面,例えば継承,多相型,抽象型などは
type classやmoduleなどで大体可能です.以下にも例があげられています.
http://www.sampou.org/haskell/tutorial-j/classes.html
http://www.sampou.org/haskell/tutorial-j/modules.html
難しいのは動的な側面,例えば並列的なメッセージパッシングに伴う
非決定性などですが,開発手法としてのOOPは主に前者に関わるので
かなりのことができるというのが相応しい評価だと思います.

260 :司馬乱:01/09/06 01:35 ID:FsBmKxpM
モナドについては,図がかけないとちょっと説明が面倒ですが,,,.
ちょっとだけ言葉で説明してみます.

248さんが言うようにどんどん伝染していっているという感覚は正しいです.
前にも書きましたがモナド関数はA->M(B)という形を基本にして考えて,
通常A->B,B->C,C->Dという関数を合成していく代わりに
A->M(B),B->M(C),C->M(D)というモナド関数をつなげていきます.
この操作が>>=の果たしている役目です.
これが通常の合成ではないところがポイントであり,
IOなどのモナド計算はこのつないでゆく所で起こると考えることができます.

さらにもう一つ必要になるのが通常の関数A->Bを
モナド関数A->M(B)に持ち上げる操作ですが,
これはB->M(B)のある関数と普通に合成してやればできます.
これがreturnの果たす役目です.
計算のモナドで本質的に重要な操作はこの二つです.

main,getChar,getLineなどはこのような形をしていないように見えますが
これは一般に()->AとAは理論的には同じと見なせるのでこのようにしています.
(これらが関数であると上記のチュートリアルにも書いてあるのはこのためです).
これは例えば,ある集合Sと,一点からなる集合{*}からSへの関数全体の集合とは,
各関数において*がSの一つの要素を決定するので
実質的に同じ集合になるのと同じようなことだと考えてください.

261 :司馬乱:01/09/06 01:36 ID:FsBmKxpM
もうひとつ.例えばgetCharの返す値はIO Char型であり,
非決定的な動作はまだ起こっていません.この段階では参照透過性は保たれています.
このIOの結果を直接参照できるならば参照透過性が失われます.例えば
unsafePerformIO :: IO a -> a
のような結果を取り出す関数があると参照透過性が失われます.
do(つまり>>=)で取り出せているように見えるのに
参照透過性が失われないのはその参照がdoの中だけだから,
言い換えれば>>=の第二引数である関数における仮引数の参照に過ぎないからです.

262 :司馬乱:01/09/06 02:49 ID:3rpwMJKc
ついでに
>>257
データ構築子と関数は別物です.
データ構築子はタグみたいなものであってデータの一部です.
実行時に評価されるわけではありません.
(言いたい事はわかりますが).

263 :司馬乱:01/09/06 02:56 ID:AQT9jsyM
>>262
ごめんなさい,寝ぼけてました.関数はfromIOのほうでしたね.
もう落ちた方がよさそうです.

264 :無名λ式:01/09/06 03:40 ID:9dUi5gVA
>>244
> 写像の連続で意味を追うというのも、疲れるね。
> 状態の変化を追う方が楽なような気もする。

うまく出来るよう訓練すればと、
状態バリバリから脱却した設計、他の言語でもかなり容易になると思われ

> どんどん伝染させていってる”ように感じるのですが、これは何のために
> やってるんでしょうか?

効能に射影して語れ、ということらしいのでIOについて考えると、

時系列情報がどこかにないと、遅延評価した時に、
本来は後から実行されるべきgetCharが先に実行されかねない。

モナドを利用すれば、モナドの皮を剥かなければ、
中身は取り出せないので、モナドの連鎖をうまく構築してやれば、
評価順序を規定してやる事が出来る。

偶数番目の文字だけリストにする関数を書いて追ってみては?

265 :日曜Haskellerオヤジ:01/09/06 08:39 ID:gIXZFRGU
>>255
うわぁ、細かい工夫はいってるなぁ。
ちなみに私の回答はといえば・・・

prim :: [Int]
prim = sieve [2..]
 where
 sieve (x:xs) = x : sieve [ y | y <- xs , y `mod` x /= 0 ]

isPrim :: Int -> Bool
isPrim n = isPrimS1 n prim
 where
 isPrimS1 :: Int -> [Int] -> Bool
 isPrimS1 n (x:xs)
  | n == x = True
  | n < x = False
  | otherwise = isPrimS1 n xs

humming = [ x | x <- [1..] , [ f | f <- factors x , f > 5 , isPrim f ] == [] ]
なーんも工夫しとらん、というか工夫できなかった(泣)・・・です。
素数は難しいです。
とりあえず、工科大のテキストは一通り終わらせたので、
やさしいHaskell入門を整理して自分用マニュアル作ってます。
概ね全体像見えてきたかなって感じです。
やっと羽根伸ばしてプログラムできるかな?

266 :デフォルトの名無しさん:01/09/06 19:45 ID:vqa/qFnw
何か面白い問題ない?

267 :デフォルトの名無しさん:01/09/06 21:24
>>264
>状態バリバリから脱却した設計、他の言語でもかなり容易に
>なると思われ

事象を写像でとらえる。ひたすら精進あるのみか。
でも写像の写像(高階関数)になると、とたんに難しくなる
んだなあ。

今読んでる本。
「プログラミング言語 武市正人著 岩波」
Haskell(Gofer)をメタ言語として普通の命令型言語を書く
というのが主題なんだが、継続のあたりまでくると
難しくてなかなか読みすすまない。
継続::状態->結果 とすると継続はプログラムカウンタに
あたるとか。うーんわからん。

XMLの本立ち読みしてたら、XSLTとかという言語があって、
これは 宣言型言語で副作用のない言語とか書いてあった。
なんか似てるね。 

268 :240:01/09/07 01:42
>>254 >>256 >>260-261

いまだに完全には理解できないのですが、IOがついてるから
大丈夫ということのようですね。
参考になるレスをありがとうございました。

269 :デフォルトの名無しさん:01/09/07 12:21
>>267

その本いくらくらいします? 本屋においてありますか?

270 :石敢當:01/09/07 15:15
>>269
書 名  岩波講座ソフトウェア科学 4
     プログラミング言語
著 者  長尾真、武市正人
出版社  岩波書店
本体価格 \3,200
発行年月 1994/06
ISBN   400010344X

近くの書店に問い合わせてみたところ、店頭にはないが
取次にあるので取り寄せまで約4日、ということでした。

私はかなり以前に図書館で借りたことがあるような気が
するのですが、読んだ記憶は無し。また借りてみようかな。

271 :バカボンぱぱ:01/09/08 00:14
 命令型言語をHaskellで書いてみる。継続によってアウトプットも出してみる。
「プログラミング言語 武市正人著」の内容をデフォルメ。

記憶状態は簡単に文字列と整数の対応(Assoc)として定義する。
type Assoc a b = a -> b
type State = Assoc [Char] Int
記憶内容へのアクセスと更新のため、次の2つを定義
mylookup :: Assoc a b -> a -> b
mylookup h x = h x
myupdate :: Eq a => Assoc a b -> a -> b -> Assoc a b
myupdate h x v y
| x == y = v
| otherwise = mylookup h y
式を次のように定義。変数、整数値、足し算と掛け算に限る。
data Expr = Var [Char]
| Num Int
| Plus Expr Expr
| Times Expr Expr
式の値を以下のようにする。
expval :: Expr -> State -> Int
expval (Var x) s = mylookup s x
expval (Num n) s = n
expval (Plus e e') s = (expval e s) + (expval e' s)
expval (Times e e') s = (expval e s) * (expval e' s)

長くなったので次に続く。
バカボンのパパは失業して、ひまなのでだらだら書くのだ。

272 :バカボンぱぱ:01/09/08 00:25
>>271 のつづき。

次に命令コマンドを定義。代入と出力だけとする。
data Cmd = Assign Expr Expr | Output Expr

最初は状態の変化を返すコマンド実行を定義。
cmdexe :: Cmd -> State -> State
cmdexe (Assign (Var x) e) s
= myupdate s x (expval e s)
cmdexe (Output (Var x)) s
= s
状態の変化は追えるけど、出力は出せませんね。
ためしに、
none :: Assoc a b
none x = undefined
s1 = cmdexe
(Assign (Var "x") (Plus (Num 3) (Num 5))) none
として、mylookup s1 "x" といれると 8が帰ってきますね。
記憶状態がnoneからs1へ変化してますね。

でもこれではアウトプットが出ない。
次へ続く。

273 :バカボンぱぱ:01/09/08 00:45
>>272 の続き。
アウトプットを出すため、継続::状態->出力を定義。
なお、ここでの出力は整数リストとする。
type Result = [Int]
type Cont = State -> Result
コマンド実行はコマンド->継続->継続とする。
cmdexec :: Cmd -> Cont -> Cont
cmdexec (Assign (Var x) e) p s
= p (myupdate s x (expval e s))
cmdexec (Output e) p s
= expval e s : p s
継続停止のため
stop :: Cont
stop s = []
準備が整ったので次のようなコマンドを実行する。
(1)xに3を代入 (2)yに5を代入 (3)yを出力
(4)x+yをzに代入 (5)zを出力
これは次のように書けます。
p1 = cmdexec (Assign (Var "x") (Num 3)) p2
where
p2 = cmdexec (Assign (Var "y") (Num 5)) p3
where
p3 = cmdexec (Output (Var "y")) p4
where
p4 = cmdexec (Assign (Var "z")
(Plus (Var "x") (Var "y"))) p5
where
p5 = cmdexec (Output (Var "z")) p6
where
p6 = stop
ここで p1 none と入れると リスト[5,8] が出力されます。
p1,p2,p3,p4,p5,p6は継続ですが、プログラムカウンタみたい
ですね。

おわり。

274 :デフォルトの名無しさん:01/09/08 03:16
オマエモナー


275 :デフォルトの名無しさん:01/09/08 22:26
ゴルァ!

276 :デフォルトの名無しさん:01/09/09 12:54
今年の ICFP Programming Contest で Haskell を使ったチームが 1 位になった模様。

http://piza2.2ch.net/test/read.cgi?bbs=tech&key=987954395&st=571&to=571

277 :石敢當:01/09/10 01:55
去年買いそこねた、というか、SOE本を買ってしまったので
買うのをやめていた、
Introduction to Functional Programming using Haskell
を買ってきました。これは second edition ということに
なっていますけれども、"using Haskell"とついているのは
2nd Ed.からなんですね。初版から10年を経て分量も100ページ以上
多くなったようです。全部で12章あり、気の向いたところを
何箇所か読んでみましたが、exampleが多くて読みやすいように
思いました。面白そうに感じたのは、7章の Efficiency,
9章の Infinite lists, そして10章の Monads です。あちこちを
パラパラ眺めたあと第10章を読んでいますが、Monads が
なんとなく分かってきたような感じがします。>>260で司馬乱さんが
書かれていることも分かってきました。

難点は高いことかな。税抜きで\9,990でした。ちゃんと読んで
中身も理解できたら安いもんですけど。

278 :デフォルトの名無しさん:01/09/10 11:42
>>277
amazonで検索したら、
Introduction to Functional Programming using Haskell
の本2種類あった。
著者がAntony J.T.DavieさんのとRichard Birdさんの。
どちらの本のこと言ってるの?

279 :デフォルトの名無しさん:01/09/10 11:44
>>277
それと、もし都内で売っている本屋あれば教えて

280 :石敢當:01/09/10 12:14
>>278
>著者がAntony J.T.DavieさんのとRichard Birdさんの。
>どちらの本のこと言ってるの?
Richard Birdさんのほうです。

>もし都内で売っている本屋あれば教えて

店内在庫があるか?という意味でしたら良く分からないです。
私は注文して買ったのですけど、国内の取次に在庫があったらしく
1週間くらいで入手できました。

ご参考までに:
http://web.comlab.ox.ac.uk/oucl/publications/books/functional/

281 :無名λ式:01/09/10 12:28
>>280
> Richard Birdさんのほうです。

お?やっぱりBirdが出してるの?(ついにHaskellか…)
じゃあ>>99で話した奴が増補Haskell版になって帰ってきたってことか…俺も買おう。

282 :デフォルトの名無しさん:01/09/10 12:32
haskellは.netに対応するそうで。。既出?

283 :デフォルトの名無しさん:01/09/10 13:17
>>282
>>183-186あたりに出てる。
つか、.NET が Haskell に対応って書くべきでは。

284 :石敢當:01/09/10 13:52
>>276
課題に出てくる SML/NG、SML/NJとは全然関係ないのね。
出題者の遊び心かな。入賞プログラムにSML/NJがなくて
出題者は残念?

285 :石敢當:01/09/10 13:53
>>82 のACMの文書を読もうと思って、大学に籍のある友人に尋ねて
みたところ、「NACSISで検索したら色々な大学に置いてある
みたいだけど、うちにはない」と言われました。

NACSIS ( http://webcat.nacsis.ac.jp/webcat.html ) という
検索サービスは始めて知りました。大学の図書館にある図書・
資料の検索ができるもので、便利そうです。

ちなみに、Introduction to Functional Programming using Haskell
(長いので次回から参照するときは「IFP本」と呼ぶことにします)を
検索したら9箇所しかありませんでした。もっとも、学科の図書室
などでNACSISの検索に引っかからないのも結構あるでしょうから、
置いてある大学はもっと多いかもしれないです。

学外者が利用できる大学図書館もあるようなので、そのうち
どこかを利用しようと思いますが、中にはコピーを1枚とるのに
100円も取るところもあるようでびっくりしました。
( http://www.lib.st.keio.ac.jp/service/annai-p6.html )
1枚100円はちょっとひどいなぁ。

286 :無名λ式:01/09/10 14:33
ACMのmembershipがあれば、
http://www.acm.org/pubs/contents/journals/surveys/
でPDF取得できるけど、高いからねー。

http://www.acm.org/pubs/contents/journals/surveys/1996-28/
は面白いの一杯あったよ。

287 :デフォルトの名無しさん:01/09/13 03:42
afe

288 :デフォルトの名無しさん:01/09/13 09:25
Haskell の欠点ってなんだろう?

289 :英語読めない人:01/09/13 10:22
>>13
現在翻訳中だってさ。

新山さん萌え。

290 :デフォルトの名無しさん:01/09/13 15:33
>>267
その本ついさっき読み終わったけど、特に後半なんかはあまり良い解説じゃないね。
いい加減な解説になってる。本書くのが大変で無理矢理本にしたって感じだね・・・

291 :石敢當:01/09/13 23:01
www.haskell.org にある "Haskell Humor" に新しく追加された
リンク The Evolution of a Haskell Programmer に昨日気づきました。
( http://www.willamette.edu/~fruehr/haskell/evolution.html )
>>4 にもある階乗のプログラムを20種以上、よくもまあと思うほど
掲載されています。書いた人の肩書きと合わせてコードを読むと
なかなか面白いです。もっとも、後半の方にあるものはあまりにも
コードが長くて真面目に読む気がしないですが(真面目に読むと
面白いのかな?)。

この元ネタとなったらしい The Evolution of a Programmer も一読の
価値あり。最後に登場する Chief Executive のところでは思わず
笑い声がもれてしまいました。

292 :デフォルトの名無しさん:01/09/14 06:17
>>288
構文が特殊

293 :デフォルトの名無しさん:01/09/14 08:52
>>292
特殊か?
どんなところがよ?
特殊だとしても欠点なのか?

294 :デフォルトの名無しさん:01/09/14 09:03
>>292
特殊とする根拠が「自分の知っている○×言語と違いすぎる」だとしたら劇萎え。

295 :デフォルトの名無しさん:01/09/14 09:11
構文が普通 => Lisp
構文が特殊 => Haskell

とか?

296 :_:01/09/14 12:06
構文が普通 => APL

でない事を祈る。

297 :デフォルトの名無しさん:01/09/15 01:18
>>288
状態が無い。
ポインタが無い。
委譲の概念が無い。
その他動的な概念が無い。
カリー化された関数が複数絡まる式が読みにくい。
習得が難しい。

298 :デフォルトの名無しさん:01/09/15 01:20
GUIやゲームなんかの俗っぽい(?)プログラミングとの親和性はどうなの?

299 :デフォルトの名無しさん:01/09/15 01:22
>>298
相当マスターしないと無理だろ。
モナドの使い方、Haskell風のプログラミングへの慣れが必要
だろ。

300 :デフォルトの名無しさん:01/09/15 02:54
型変数の辺りとか>>293

301 :デフォルトの名無しさん:01/09/15 05:14
仕様の変更に対応しづらそう>>298
GUIやゲームは仕様変更の連続だから
(偏見かしら?)

302 :デフォルトの名無しさん:01/09/15 05:25
>>301
仕様変更への対応のしやすさは、プログラミング言語よりも
仕様そのものの構成に依存するのではないかと思うけど。

303 :デフォルトの名無しさん:01/09/15 05:42
Goferってどうでしょう?

304 :デフォルトの名無しさん:01/09/15 06:38
>>303
いいっすよぉ。ほとんど Haskell 。とうか、Haskell の仕様は
Gofer の実装後に確定したものが結構多いです。Monadic IO も
Gofer での実装が先だったと思います。

作者の Mark P. Jones 自身が実装についてのレポート
"The implementation of the Gofer functional programming system"
を書いていて、これを読みながら、処理系のソースを読むと大変勉強
になります。このレポート読んでソースをイジッテ自分で新しい機構
を追加するなど、しゃぶり尽くすに最高です。

gofc という C へのトランスレータが付属していて、これを
改造して、gofhoge というのをつくるというのはどうですか。

305 :デフォルトの名無しさん:01/09/15 08:58
>>304
比較的小さくて良い感じですね。

306 :デフォルトの名無しさん:01/09/15 09:25
ここ読んでもモナドについてはっきりしない。
「副作用が含まれる部分をモナド部分に分離できる。」
なのか、
「モナドだから副作用では無い。」
なのか、はっきりして欲しい。

それから、英語でも学術的な内容でも構わないからモナド
がはっきりわかるように詳しく解説した文献何かない?
やはりBirdの本が良いのか?

307 :石敢當:01/09/15 13:00
>>306
http://www.research.avayalabs.com/user/wadler//topics/monads.html

ここに行くと Philip Wadler氏 が書いたMonadに関する文書を
いくつか見ることができます。メーリングリストで、この中にある
"Comprehending monads" をお薦めしている人がいたので近々
読んでみようかと思っています。私はまだ読んでいませんので、
この文書が「モナドがはっきりわかるように詳しく解説した文献」
かどうかは分かりません。

もしどなたか読まれた方がいらっしゃればコメントを頂けませんか?

308 :デフォルトの名無しさん:01/09/15 16:54
モナドってお菓子ありそう。
ナボナ

309 :デフォルトの名無しさん:01/09/15 17:02
>>306
モナドってただ単に高階関数作って
操作を順序付けするって事なんじゃないの?

310 :デフォルトの名無しさん:01/09/15 18:19
>>309
全然答えになってない。

311 :デフォルトの名無しさん:01/09/15 18:44
>>310
模範解答してくれyo!

312 :デフォルトの名無しさん:01/09/15 18:50
>>309
もしそうだとしたら、何でIO処理がモナドなんですか?

313 :デフォルトの名無しさん:01/09/15 18:58
IO処理は順序付けが必要だから>312

314 :312:01/09/15 19:36
順番つけるだけ?だとしたら副作用は許容されるの?

315 :デフォルトの名無しさん:01/09/15 19:51
>>314
副作用は、
状態を高階関数の引数で受け取る様にすればいい。

316 :312:01/09/15 20:05
>>315
それだと、自分で状態を与えなくてはいけなくなりません?
状態を読み取る時はどうするんですか?
また外部からの入力で与えられた変化にはどうやって
対処するんですか?

317 :デフォルトの名無しさん:01/09/16 08:08
haskellは知らんのでschemeでのmonadのサンプル
for-eachに渡るリストをmonadのストリームと見なします。

(define (do-monad-output action . monad-stream)
 (for-each
  (lambda (x) (if (procedure? x) (action (x)) (action x)))
  monad-stream))

(define (do-monad-input action . monad-stream)
 (for-each
  (lambda (x) (if (procedure? x) (x (action)) (action)))
  monad-stream))

318 :デフォルトの名無しさん:01/09/16 08:09
出力
(do-monad-output display
 "a b c 3と出力:"
 (lambda () 'a) " "
 (lambda () 'b) " "
 (lambda () 'c) " "
 (lambda () (+ 1 2)) "\n")

result>a b c 3と出力:a b c 3

319 :デフォルトの名無しさん:01/09/16 08:11
入力
;副作用のある入力
;(文字列中の文字を一文字ずつ返すclosureを作成して返す)
(define (make-getchar s)
 (let ((pos 0))
  (lambda ()
   (if (< pos (string-length s))
     (prog1
      (string-ref s pos)
      (set! pos (+ 1 pos)) ;副作用
     )
     #f))))
(define (putchar ch) (display ch))
(define skip 'skip)

(do-monad-input (make-getchar "a b c 3と出力:")
 putchar skip
 putchar skip
 putchar skip
 putchar skip)

result>abc3

320 :デフォルトの名無しさん:01/09/16 08:12
出力で(lambda () 'a)
としているのは、遅延評価の代わりです。(delayでも良かった)

321 :306:01/09/17 00:21
>>307
お、さんきゅ。

>>309
副作用を起すためには命令の順序を明確にしないといけないのは
確かだが、monadoってそういう意味なのか?
リストさえ作れば順序ぐらい明確になるだろ。

>>317-319
やってることはわかるがaction関数で副作用が起こってるように
しか見えない。
やはりmonado内で副作用を起すのが目的ってことか?

322 :_:01/09/17 00:43
>>321
> 副作用を起すためには命令の順序を明確にしないといけないのは
> 確かだが、monadoってそういう意味なのか?
> リストさえ作れば順序ぐらい明確になるだろ。

遅延評価する処理系でも?
applyによるズル剥けに注目

323 :317-320:01/09/17 02:48
何が重要なのかと言うとdo-monad-output(またはdo-monad-input)
を呼び出さない限り、何も起らないという事です。したがって、
monad-stream(ここではリスト)は処理自体ではなく、単にその見込みを
表現しています。monadが適用される場合に限り、actionが強要されます。
haskell識者の見解をお願いします。

324 :司馬乱:01/09/17 03:41
>>323
評価戦略によらず評価順序を定める例としては面白いですね.
ただ,for-eachがリストの順序どおりに処理するということを
仮定しているという点では,これはシミュレーションですよね.
それに本来のモナドのモジュール化と切り分けが異なるし用語法が違うので
両方を理解していないと混乱を招くと思います.
例えばHaskellの>=に当たる部分がdo-monad-*に含まれてしまっているし,
putcharやskipの部分をモナドと呼ぶのは適切ではありません
(Haskellの用語としてもカテゴリー理論の用語としてもおかしいです.
どこかでこういう用法をご覧になられたのですか?).
むしろこちらをアクションといった方がHaskellの用語に近いと思います.
そもそも切り分けが違うのでどうやってもぴったりは合いませんが.

325 :司馬乱:01/09/17 04:12
>>321
あと副作用については話が混乱してますが書いてる時間がないな.
一言で言うと,環境の変化という副作用と新たに実装する副作用は
別だということです.モナドでできるのは後者です.
schemeの例ではその部分ははしょって
そのままschemeの破壊的操作を使っていますね.
これも混乱のもとかな.

326 :名無しさん@vim6:01/09/18 17:36
age

327 :デフォルトの名無しさん:01/09/18 19:23
[1..100] >>= (\x -> "age ")

328 :デフォルトの名無しさん:01/09/18 19:37
で、モナドの決着はついたの?

329 :デフォルトの名無しさん:01/09/18 19:42
全然わからん。

330 :デフォルトの名無しさん:01/09/18 19:56
モナドを使った短小プログラムぎぼん。

月並みだけど、小文字入力すると大文字出するやつ
toBig = getLine >>=
(\s -> if s == ""
then putStr "\n"
else (putStr (s >>= (\c -> [chr (ord c - 32)]))
>> putStr "\n" >> toBig))

331 :デフォルトの名無しさん:01/09/18 22:55
>>330
toUpper 使おうよ。

332 :英語読めない人:01/09/20 02:31
n+kパターンって
dec (n+1) = n
ってやつですか?

333 :デフォルトの名無しさん:01/09/20 02:56
ナニソレ

334 :デフォルトの名無しさん:01/09/20 03:12
>>333
よくしらんけど
http://www.haskell.org/onlinereport/preface-13.html#sect1.4

335 :デフォルトの名無しさん:01/09/20 21:04
http://www.pro.cs.titech.ac.jp/~tomo/programming.html

ここで言ってるCPSって何よ?

336 :デフォルトの名無しさん:01/09/20 21:03
Haskellで実用的なコード書いる人いるの?
つーかHaskellで実装可能な
実用的なコードってどんなの?

337 :デフォルトの名無しさん:01/09/20 21:42
> Haskellで実用的なコード書いる人いるの?
書ける人はいる。書いてる人は少ない。多分。

> つーかHaskellで実装可能な実用的なコードってどんなの?
質問の意図が微妙。
Haskell で書かれた実用的なプログラムのコードが見たいのか?

338 :デフォルトの名無しさん:01/09/20 22:20
「VB で書かれた有名なソフトって何があるの?」
みたいな意味だと推測。

339 :デフォルトの名無しさん:01/09/20 22:40
>>335 Continuation Passing Styleだね。
継続を渡す奴だ。って俺もまじめに使ったことない。

340 :336:01/09/21 00:14
>337
言語って基本的に問題を解決する手段だと思うんだけど
Haskellっていったいどんな問題を解決するのかって事。

VBよりGUIが作りやすく、Perlよりお手軽で、C++より大規模開発に向くのか、
それとも単にマニアが習得を「目的」にしているのか?とかね。

MLかHaskell覚えようかなと思ってるんだけど、
応用がきかずに結局習得しただけだったってのも悲しいので。

341 :デフォルトの名無しさん:01/09/21 01:03
>>340
>VBよりGUIが作りやすく、

現在はGUIを作るライブラリがそもそも無いんじゃないか?
ただ、将来はHaskell.NETが出るらしいからそれで劇的に状況が
変化するかも知れない。

>Perlよりお手軽で

インタプリタはあるし、簡潔な表現は出来る。だが、慣れないと
難しいという意味ではお手軽とはいえないかもしれない。
ライブラリの多さにも疑問が残る。

>C++より大規模開発に向く

モジュールシステムはあるが、C++のクラスに相当するものは無い。
これは意見が分かれるところだろう。

MLかHaskellなら、挫折が嫌ならML、理解力に自信があるならHaskell
という選びかたをすればいいと俺は個人的に思う。

342 :デフォルトの名無しさん:01/09/21 01:20
> 現在はGUIを作るライブラリがそもそも無いんじゃないか?
ありますよ。
http://www.haskell.org/libraries/#guigs
でも Haskell で GUI は大変そう。

> C++より大規模開発に向く
俺は Haskell のほうが断然向いてると思うよ。

343 :デフォルトの名無しさん:01/09/21 01:46
>>342
使ったこと無いけど、なんか全部UNIX系のっぽいし、日本語通らなそうだね。
これは偏見で悪いけど、多分使いもにならないんだろうな。

344 :デフォルトの名無しさん:01/09/21 02:28
>>343
まあ,ちょっと前のRubyなんかと状況は同じと思えばいいんじゃない?

345 :デフォルトの名無しさん:01/09/21 02:54
age

346 :デフォルトの名無しさん:01/09/21 20:09
>>343
たとえば日本語文字列をRubyなみに簡単に取り扱うには、
組み込みの関数ではぜんぜん足らないので、自作するか、
誰かが作ってくれるのを待つしかない。そういう意味では
「実用性に乏しい」と言えるだろうね。

さらに言えば、MLやHaskellの強みって、robustなプロ
グラムを支援するところだと思うんだけど、いわゆる
「実用的なプログラム」の世界ってのは、robustである
ことよりも、むしろquick and dirtyであることが期待
されていることが少なくないよね。そういう意味ではML
やHaskellは「実用的」ではないと言えるでしょう。

これは僕の期待だけど、任意の言語から呼び出し可能な、
robustなライブラリってのはすごくニーズがあると思う。
MLなりHaskellなりで書かれた関数が、シームレスかつ効
率的にRubyあたりから呼び出し可能だと、すごくありがた
い。

347 :デフォルトの名無しさん:01/09/21 20:31
>>346
Haskellはccallで直接C関数が呼び出せるし8-bit cleanだから,
後はどれだけよってたかって整備するかというstatusだと思うけど.
素性として実用的ではないというのと,現時点で実用的でないというのは違うしね.

>任意の言語から呼び出し可能な、robustなライブラリ
っていうのはどっちかって言うと.NETの世界かな?能書き通りにいけばだけど.

348 :デフォルトの名無しさん:01/09/21 20:44
お前等sageすぎ
真面目な話してるときぐらいageようや

349 :デフォルトの名無しさん:01/09/21 21:11
>>346
>robustなプログラム
例えば、原子炉制御システムのプログラムに、プログラム正当性の証明も付けて
提出したとか、そういうことですか?

350 :げーでる:01/09/21 21:13
>プログラム正当性の証明
無理です

351 :ホーア:01/09/21 21:34
>>350え!?

352 :チューリング:01/09/22 00:08
おめーら、遊んでる場合か〜!
御仕置だべ〜!

353 :デフォルトの名無しさん:01/09/22 11:20
モナドどうなったのよ?
あの説明でいいの?

354 :デフォルトの名無しさん:01/09/22 23:06
モナドはモジュール化のタメにあるのです。

355 :デフォルトの名無しさん:01/09/22 23:17
R
R
R
R
R
RR
RRU
UUUU

UBBBBBBBBYYYYYYYYYYRRRRRRRRRUUUUUU
BBBBBBBBYYYYYYYYYYRRRRR
RRRRUUUUUUBBBBBBBBYYYYYYYYYYRRRRRRRRRUUUUUUBBBBB
BBBYYYYYYYYYYRRRRRRRRR
UUUUUUBBBBBBBBYYYYYYYYYYRRRRRRRRRUUUUUUBBBB
BBBBYYYYYYYYYYRRRRRRRRRUUUUUUBBBBBB
BBYYYYYYYYYYRRRRRRRRRUUUUUUBBBBBBBBYYYYYYYYYY

356 :デフォルトの名無しさん:01/09/23 02:49
>>355
ああウザイ

357 :英治:01/09/23 03:19
英治

358 :デフォルトの名無しさん:01/09/23 15:52
>>355
shigeは帰っていいよ。
おまえのようなアフォには関数型言語は高級すぎる。

359 :age:01/09/23 22:13
age

>>356 >>358
反応するな。
放置せよ。

360 :石敢當:01/09/24 23:01
GHC 5.02 がリリースされました。
5.00 - 5.00.2のときは提供されていなかった(と思う)Windows版の
バイナリーもあります(26.1MB)。ただ今ダウンロード中……。

361 :デフォルトの名無しさん:01/09/25 01:12
>>360
Mucho hacking on the .NET code generator, including some FFI
extensions for .NET interop. It's still severely b0rk3d,
so won't do anything useful. Yet.

だって.ほんとにやってるのね.

362 :デフォルトの名無しさん:01/09/25 01:24
ヨ−ロッパの方ではコンピュ −タサイエンスの学科の人が初めて教わるプログラミング言語が Haskellだということが結構あるらしいですね。

363 :デフォルトの名無しさん:01/09/26 20:17
Amazonから
Introduction to Functional Programming using Haskell
second edition by Richard Bird
が届いた。Prefaceにこの本はプログラミングの経験は必要と
していないが、数学的推論の素養は必要とするとある。

364 :デフォルトの名無しさん:01/09/26 20:25
追加。
この本は1年生のプログラミング教育に最適とある。
University of Oxford で。

365 :名無しさん@vim6:01/09/27 15:19
>>363
私もその本を注文しました。
もう一冊の洋書も併せて注文しましたが、
いろいろ小面倒なルートを経て手元に来るらしいので、
あと1ヶ月はかかりそう(爆)
やっぱりamazonは偉大ですね…

366 :石敢當:01/09/27 16:03
>>360
いくつか不備があったということで、新しいバイナリーが再アップ
されています(26.7MB)。

>>365
私もある洋書を近くの書店で注文したら1週間ほど経過した頃に
「入手できない」と言われ、アマゾンで注文したところ、約2週間で
届きました。初めて利用しましたが、配送料も取らないみたいですし
なかなか便利です。

367 :石敢當:01/09/27 17:31
初めてGHCiを使ってみました。
Hugsと同じ感覚で使えるのですぐに使えます。
ファイル読み込み時に

Compiling Main

などと表示されるので、読むと同時にコンパイルもしているので
しょうか(マニュアルをまだよく読んでいない)。
そのせいかどうか、実行速度が速いです。Hugsで40秒弱かかる
プログラムがGHCiでは6秒ほどで終わりました。

368 :デフォルトの名無しさん:01/09/27 18:40
HaskellとSchemeってどっちが良い?

369 :デフォルトの名無しさん:01/09/27 18:48
1年生にを教えるプログラム
MITではScheme、OxfordではHaskellらしいが本当?

370 :デフォルトの名無しさん:01/09/27 18:52
そんな事よりも
SchemeとHaskellの違いが知りたい
SchemeはMIT発祥だから・・・

371 :名無しさん@お腹いっぱい。:01/09/27 18:53
Schemeの方が簡単だと思うけど

372 :scheme使い:01/09/27 20:47
schemeすぐわかったけど、
haskellわけわからん。

373 :scheme使い:01/09/27 20:53
>>370
違いなんて、見ただけでわかると思うけど?

374 :デフォルトの名無しさん:01/09/27 21:02
見た目の違いじゃないだろ(笑)

375 :scheme使い:01/09/27 21:03
ところで、
「haskell使い」と自分で名乗れる様な人はこの板にいるの?

376 :scheme使い:01/09/27 21:04
モナド解説してほしいので

377 :デフォルトの名無しさん:01/09/27 21:27
>scheme使い
うざい。

378 :デフォルトの名無しさん:01/09/27 21:30
とりあえず、見ただけでわかった違いを言ってみろよ
どーせ、どっちも使えないカスなんだろ

379 :デフォルトの名無しさん:01/09/27 21:39
Scheme 正格
Haskell 非正格 遅延評価

380 :名無しさん@お腹いっぱい。:01/09/27 23:08
こういうつらない話題は止めよう。
Schemeは別スレがあるからそっちで
やるのがよろし。
比較するのは関数言語スレでお願いします。

381 :司馬乱:01/09/28 00:06
ちょっと前にGUIの話が出てましたが
http://www.haskell.org/mailman/listinfo/
にあるHaskellやGUIのメイリングリストで,
汎用GUIインタフェースの設計について色々議論されています.
ログも見ることが出来るので英語を苦にしない方は覗かれるといかがでしょう.
この手の議論って結構楽しいんですよねー.

382 :デフォルトの名無しさん:01/09/28 00:16
で、モナドは?

383 :デフォルトの名無しさん:01/09/28 02:00
やっぱHaskellとSchemeの最大の違いは型システム
だろうね。
あと、Schemeが状態バリバリの命令型に近い言語に
対して、Haskellはモナドをバリバリに使わない限り
関数型のスタイル。

384 :デフォルトの名無しさん:01/09/28 06:41
Haskellで何か実用的なものを作ろうとしたら
何がいいかな?

385 :デフォルトの名無しさん:01/09/28 08:21
>>384
正直言ってWindowsではGUIさえ出来ればいろいろ
作れると思うのだが、GUIが出来るのかどうかが
問題だな。

386 :デフォルトの名無しさん:01/09/28 08:22
Windowsに限らずGUI無しで実用的なプログラムは
ちょっと思いつかない。

387 :デフォルトの名無しさん:01/09/28 08:53
>>385
おまえ、>>342にあるURLのpage見ろよ。
>>386
おまえ、programmer止めた方がいいよ。

388 :デフォルトの名無しさん:01/09/28 10:25
>>387
なら何か提案しろyo!

389 :名無しさん@vim6:01/09/28 14:11
Win中心に物事を考えるのって、なんか寂しいよね…

390 :デフォルトの名無しさん:01/09/28 14:27
基本はコンソールだ!ゴルァ!!
やっぱりダメなものはダメって言わないと! ぁぅぇ?

391 :デフォルトの名無しさん:01/09/28 15:25
で、Haskellで作ると良い実用的なアプリって何?

392 :デフォルトの名無しさん:01/09/28 18:53
別にHaskellは汎用言語なんだから、何でも好きなものを
作ればいいんじゃないの。現状の処理系で気軽に作れる実
用的なアプリって話だと、たとえばXMLパーザとかHTML構
文チェッカなんかはどうかね。正当性の確認みたいな作業
は、厳密さが価値だからね。

393 :デフォルトの名無しさん:01/09/28 21:13
haskellの様な型推論ありの処理系を、
自分で作るとなると難しいでしょうか

394 :デフォルトの名無しさん:01/09/29 08:53
>>393
言語仕様によるとしか言えないよね。

395 :デフォルトの名無しさん:01/09/29 18:17
たまにこのスレに出てくる「モナド」って、
何の事ですか?

396 :デフォルトの名無しさん:01/09/29 19:29
>395
I/Oの多いプログラムの事を「モナ度が高い」と言います。

397 :デフォルトの名無しさん:01/09/30 02:11
ソウカモナ…

398 :デフォルトの名無しさん:01/09/30 09:31
ruby撲滅スレ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=1001125342
ruby撲滅スレ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=1001125342
ruby撲滅スレ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=1001125342
ruby撲滅スレ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=1001125342
ruby撲滅スレ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=1001125342
ruby撲滅スレ
http://piza2.2ch.net/test/read.cgi?bbs=tech&key=1001125342

399 :デフォルトの名無しさん:01/10/01 09:50
type で作った型シノニムを class の instance にしたいと、よく思う age

400 :デフォルトの名無しさん:01/10/01 18:54
http://www.genpaku.org/monadj.html

401 :デフォルトの名無しさん:01/10/01 19:47
ヴィトゲンシュタインの哲学書のようなモナドってなあに?

402 :デフォルトの名無しさん:01/10/01 23:41
>>400
楽しい?

403 :デフォルトの名無しさん:01/10/02 10:49
>>402
まったく関係ないわけでもないのだけど…

404 :デフォルトの名無しさん:01/10/02 14:30
>>1発見!

http://cocoa.2ch.net/test/read.cgi/unix/990764339/300-305
>>365

405 :デフォルトの名無しさん:01/10/02 14:59
>>255
hugs98/demos/Examples.hs でこんなもの見つけた。

hamming :: [Integer]
hamming = 1 : (map (2*) hamming || map (3*) hamming || map (5*) hamming)
where (x:xs) || (y:ys) | x==y = x : (xs || ys)
| x<y = x : (xs || (y:ys))
| y<x = y : (ys || (x:xs))

406 :石敢當:01/10/02 23:15
>>405
hugs98/demos の下はそのうちゆっくり見ようと思いながらまだ
見ていませんでした(見た記憶があるのはQueen.hsくらいかな)。

この hamming 、とても速いです。しかも私が作ったものとは違って
ちゃんと小さい順序にならんでいるし・・。コードを見ると、
「ああ、なるほど」とは思いますが、自力じゃなかなか思いつかない
ような気がします。修行が足りないなあ。

ところで、このハミングの綴りは Examples.hs にある hamming が
正しいようですね。

407 :デフォルトの名無しさん :01/10/05 04:30
age

408 :石敢當:01/10/06 11:31
Haskellは趣味でいじっているだけので、本業が忙しくなると全然遊ぶ
時間が取れず困ります。

>>286
>ACMのmembershipがあれば、
http://www.acm.org/pubs/contents/journals/surveys/
>でPDF取得できるけど、高いからねー。

比較的そばにある図書館で読めることは分かったのですが、なかなか
足を運ぶ時間が取れないし、いちいちコピーするのも面倒なので
ACMのmembershipを買ってしまいました。高いことは高いですが、
読みたいと思ったものがあったときに自宅ですぐダウンロードできるのは
やはり便利ですものね。

http://www.acm.org/pubs/contents/journals/surveys/1996-28/
>は面白いの一杯あったよ。

記事の数がとても多くてタイトルを眺めるだけでも結構時間がかかります。
いずれ時間ができたときにゆっくりと見てみたいです。

409 :名無しさん:01/10/07 16:20
>>408
俺も研究の方が忙しくて、なかなか手が出せない。
つい最近、アッカーマン関数を定義したけど(笑)
acker :: Integer -> Integer -> Integer
acker x y
| y == 0 = 0
| x == 0 = 2 * y
| y == 1 = 2
| otherwise = acker (x - 1) (acker x (y - 1))
たったこれだけ…。
けど、C言語を泣く泣く使うよりも楽しいな。

410 :デフォルトの名無しさん:01/10/08 19:20
age

411 :デフォルトの名無しさん:01/10/08 19:30
なにが楽しいのかわからん

412 :デフォルトの名無しさん:01/10/09 23:44
monadはmonoid(群のなりそこない)のパクリらしいとの
話もあるが本当か?

413 :デフォルトの名無しさん:01/10/10 20:17
あるかのいど!
あるかで思い出したけど
アルカードはドラキュラのアナグラム

414 :デフォルトの名無しさん:01/10/10 20:24
へぇー!

415 :デフォルトの名無しさん:01/10/11 00:10
>>412
http://www.matematik.su.se/~haberg/で許してくれないか…

416 :デフォルトの名無しさん:01/10/11 00:11
monoid 単位半群

http://www.gavo.t.u-tokyo.ac.jp/~hosoyama/softkiso/soft1b.html

417 :デフォルトの名無しさん:01/10/11 00:52
Wadler先生のMonadの論文が日本語で解説されてるぞ。
monoidも説明されてる。
http://www.is.titech.ac.jp/~kando9/work/Progress/Monad/Monad.html

418 :デフォルトの名無しさん:01/10/11 01:51
>>417
さっぱりわからないけど、IO aというのは意図だったのか。
値が違っても意図は同じだから、意図は参照透過って意味ならなんか納得。

419 :デフォルトの名無しさん:01/10/14 10:22
Category theorists are infamous for stealing terms from
philosophy, starting with the theft of category itself
from Kant. The abduction of monad from Leibniz was aided
and abetted by the pun on monoid. (by Richard Bird)

420 :デフォルトの名無しさん:01/10/16 16:16
Haskell で計算量 O(1) で挿入、削除を出来る queue を作れますか?

421 :デフォルトの名無しさん:01/10/17 09:14
>>417のリンク先を書いた人の趣味:
http://www.nerimadors.or.jp/~chihiro/

422 :デフォルトの名無しさん:01/10/17 10:15
ステキ

423 :デフォルトの名無しさん:01/10/17 15:50
http://mentai.2ch.net/test/read.cgi/philo/1002692332/
ライプニッツマンセー

424 :デフォルトの名無しさん:01/10/17 19:13
モナド理解できない。イロイロ妄想が膨らむなあ。
アマゾンみてたらこんなのもあった。

唯心論物理学の誕生―モナド・量子力学・相対性理論の統一モデル
と観測問題の解決
中込 照明 (著)
ライプニッツのモナドを論をヒントに観測問題をついに解決!
意志・意識を物理学の範疇に取り込んだ新しい究極の物理学。
コペルニクス的転換の書。

425 :デフォルトの名無しさん:01/10/17 19:19
観測問題ってのは解決しないから問題として取り上げられる
もんだと思ってたけどちがうんか。。。

426 :ニュートン:01/10/17 19:37
ライプニッツごとき盗人の話を信じてはいかん。

427 :デフォルトの名無しさん:01/10/17 19:39
最近このスレ廃れてきてるよな…。
もう潮時かね…。

428 :名雪:01/10/17 20:06
>>427
スレ半分まで来たんだおー。あと一息だおー。

429 :デフォルトの名無しさん:01/10/17 20:13
ここが正念場、これを乗り切ればSchemeスレのように黙っていても
スレが育つようになります>>427

430 :石敢當:01/10/18 00:21
>>420
このあたりの議論はIFP本(>>277)に詳しく書かれているようです。
まだちゃんと読んでいませんので、O(1)で実現できるのかどうか
理解していません。また、関数型言語向けのデータ構造については
Chris Okasaki 氏の本(>>7)が詳しいです。
内容のない投稿ですが、スレを伸ばすためということでご勘弁を…。

これらの本をゆっくり読みたいなぁ。。。

431 :デフォルトの名無しさん:01/10/18 06:51
モナドは理解するのは諦めて、使い方を学ぶことだけに
徹するのが良い。
使えるだけで十分。

432 :デフォルトの名無しさん:01/10/18 07:59
言葉を学ぶことはその用法を、ってやつだね

おれもさっさと用法をマスターしないとw

433 :デフォルトの名無しさん:01/10/18 18:47
>>424
電波くせー

434 :デフォルトの名無しさん:01/10/19 02:13
Haskellって日本語の本はないんですよね?
このスレを興味深く読んでたんですが何から
読み始めればいいのやら

435 :デフォルトの名無しさん:01/10/19 02:20
>>434
>>2にある日本語サイトである程度学べるよ。

436 :デフォルトの名無しさん:01/10/19 02:39
>>435
ありがとうございます。
最近寂しいこのスレを盛り上げられるよう勉強して
いきたいです。

437 :デフォルトの名無しさん:01/10/19 05:26
>>435 436です
http://www.amazon.co.jp/exec/obidos/ASIN/4756103170/
とりあえず古本屋で買ってそのままになってた
こっちから勉強します。関係あるかどうかよく分かんないん
ですが関数の集合的な記述の仕方とかためになりそうなんで、
まずはこれをやってからにします。

438 :デフォルトの名無しさん:01/10/19 19:40
O(1)で動くQueueのことちょっと考えたが、
Queueの前に配列ってHaskellでどうimplementする?

配列をリスト使って、(!!)演算子使ってindex指定し
ても、O(n)かかるしな。

439 :デフォルトの名無しさん:01/10/19 19:44
ようするに、O(1)で作動する配列(Array)を教えてくれ。

440 :420:01/10/19 20:00
>>438-439
import Array
ではいかんのですか?

でもリングバッファみたいなやりかただと
要素数が限られてきて、一杯になったときのことを考えると
ちょっと不満だったり。
まあ、実際に使う分には、うまくやれば大して問題ないだろうが。

>>430
英語の本か…
とりあえず Chris Okasaki 氏の edison ってライブラリ
http://www.cs.columbia.edu/~cdo/edison/
に queue があるのでそれを読んでみている。

でも、実際には stream が queue みたいなものだし、
Haskell でプログラミングしていて queue が必要になることは
あまり無いのかも。
-- 実際必要になっても O(1) じゃなくてもいいなら手はあるし。

なんか、うまくやれば、綺麗に実装出来そうな気もするんだがねぇ。

441 :デフォルトの名無しさん:01/10/19 20:51
>>440
サンキュー。
ライブラリーにあるArray.hs見たけど、修業たりなくて
すぐにはわからないな。

442 :デフォルトの名無しさん:01/10/19 20:54
>>441
Array は primitive ばかりで見てもわからなくってあたりまえ。

http://www.sampou.org/haskell/library-j/array.html
こっち見てくれ。

443 :デフォルトの名無しさん:01/10/19 21:07
お、ライブラリの解説があったんだ。
>>442
ありがとう。これから読んでみる。

444 :デフォルトの名無しさん:01/10/19 23:25
HaskellでHashとか実現できるんですか?
データを保持する「変数」がないから、どうなんだろう?

445 :デフォルトの名無しさん:01/10/19 23:36
444オメデトウ>444

446 :デフォルトの名無しさん:01/10/19 23:42
>>444
出来ますよ。
というか、ハッシュ法と変数(というか代入)は関係ないような。

ってなんか語弊がありそうな表現だな…。

447 :デフォルトの名無しさん:01/10/20 00:18
>>446
>出来ますよ。
それは自然に、あたりまえにできるという意味ですか?
精いっぱいがんばって(それでも遅いけど)、なんとかできました、
って事じゃないのですか?

448 :デフォルトの名無しさん:01/10/20 00:56
へ?そんなの当たり前に出来るだろ。標準のライブラリに無かったか?

449 :デフォルトの名無しさん:01/10/20 01:04
標準のにあったぞ。
assocs :: (Ix a) => Array a b -> [(a,b)]
assocs a = [(i, a!i) | i <- indices a]

450 :446:01/10/20 01:47
>>449
それっって違うんじゃ…。

>>447
まあ、自然にできますな。大した苦労もせず。
といっても、処理系が配列を巧く扱ってくれないと遅くはなるかもしれないが
大抵はうまくやってくれるかと。
つか配列の話はハッシュに限ったことじゃないな。

451 :デフォルトの名無しさん:01/10/24 12:12
age

452 :デフォルトの名無しさん:01/10/25 13:09
正直、Lispを越えられるか?と思ってHaskellを勉強したんだけど
Lispの強力な記述能力を超えられると思う?

453 :デフォルトの名無しさん:01/10/25 14:51
>>452
もしかすると、超えてないかもしれないけど、Haskellと同等の記述をLisp
で得るにはHaskellインタプリタをLispで書くのと同じぐらいの労力を払った後、
やっと出来るようになる、と思う。

454 :デフォルトの名無しさん:01/10/25 15:21
>>452
つまらん答だが柔軟性と安全性のどちらに体重をかけるかによる.
記述能力といっても一種類じゃない.

455 :デフォルトの名無しさん:01/10/25 15:44
>>454
あと、理解のしやすさや簡潔さも。
これを無視すればアセンブラが一番柔軟とも言えるよね。

456 :デフォルトの名無しさん:01/10/25 16:14
>>455
Haskellも楽しいけどこういうのもなかなか.
ttp://www.csl.sony.co.jp/person/fnami/asm.htm

457 :デフォルトの名無しさん:01/10/25 19:18
LISPのインタープリタをJAVAで書いたことがあるが、
Haskellのインタープリタも書いてみたい。
遅延評価ってどう実装する?
LISPの評価は関数呼び出して、その結果を受けるだけと
素直だが、遅延評価はどないしよう。
イベント送信して受信するようなことするか???

458 :デフォルトの名無しさん:01/10/25 19:23
IOモナドは意図なのか
俺のような初心者に実感のある関数(例えばf1とf2とする)
はたとえ高階関数であっても引数にapplyさせてみて返って
きた値(実感のある数や文字列だとする)を見比べればf1と
f2が同じか違うかをなんとなく感じることができるけど
IOモナドはどうやって比べられるのだろう?IOモナドに何か
applyさせても返ってくるのはIOモナドなんだよね。出力を
見比べていいの?出力は副作用の結果だから比べちゃいけ
ないような気がしたんだけどそんなことない?

459 :デフォルトの名無しさん:01/10/25 19:35
おれもIOわからん。
IO :: ((IOError -> IOResult) -> (a -> IOResult) ->
IOResult) -> IO a

460 :デフォルトの名無しさん:01/10/25 20:38
>>457
効率よく実装するのは大変だが、安直にやるなら…
直感的には、すべての関数呼び出しの実引数をdelayでくるんで、
仮引数を参照するときにforceを付ければよい。

461 :デフォルトの名無しさん:01/10/25 20:56
>>458-459
Worldという、コンピュータの全状態を表す型があるとする。
もちろんこの型のオブジェクトは1つしか存在しない。
IO tは「Worldを受け取り、状態を変化させたWorldを返すコマンド」型。

例えば
putChar :: Char -> IO ()
は、「Charを与えると、IOコマンドが返ってくる」関数。
返ってきたコマンドにWorldを与えると、状態が変化したWorldが返る。

main = do
    putChar 'a'
    putChar 'b'
とすると、mainはIO ()型になる。
システムがこれにWorld型の引数を与えて呼び出す。

ミソは、このインターフェースだとWorld型のデータに直接さわれないこと。
なので、「状態が変化する前のWorld」と「変化したあとのWorld」が
同時に存在して困る、などということが起きない。

462 :デフォルトの名無しさん:01/10/25 23:03
>>459
サンクス。なんとなくわかったような。
delay, force ってメソッド? javaやlispにはないよね。

463 :デフォルトの名無しさん:01/10/25 23:07
>>453
> Haskellと同等の記述
ってどの程度のこと言ってるの?
遅延評価だけなら結構簡単にできるよね?
型システムも?
curried function とかも?(これは簡単そう)

どうでもいいけど、curried function と S式って、相性悪いよな…。

464 :デフォルトの名無しさん:01/10/25 23:08
>>461
おおよそ IO::World -> World って感じなのかな。
IO t でtに( )以外の値とることある?

465 :デフォルトの名無しさん:01/10/25 23:22
>>463
>curried function と S式って、相性悪いよな…。
そうかなあ? S式は一つ目に関数名がきて、後は
引数がだらだら続くから、curryのように思える。
そんなに相性悪くないと思うが。。。

466 :463:01/10/25 23:30
>>465
Haskell 風に書くと
f :: a -> b -> c -> d
のような関数があると
((((f a) b) c) d)
って書かないといけないような…。

(f a b c d)
((f a b c) d)
(((f a) b c) d)
のような書き方も合法とするのは、なんだかねぇ…。

と、俺は思うのだが…。なんかズレてる?

467 :デフォルトの名無しさん:01/10/25 23:40
>>462
delayとforceはSchemeにあるよ。

>>464
まあそう。IOは、最初はST(State Transformer)と呼ばれてた。
getCharはIO Char型だよ。
do
 c <- getChar
 putChar c
は、実はsyntax sugarで、getChar >>= \c.(putChar c)のこと。
(>>=)はIO a->(a->IO b)->IO b型の演算子。

システムは、まずWorldを引数にgetCharを呼び出す。
返ってきたIO Char型の構造体からCharを取りだし、
\c.(putChar c)を呼び出すと、IO ()が返ってくる。
それをWorldを引数に呼び出す。

468 :司馬乱:01/10/25 23:40
>>464
もちろんあるよ.
World->Worldっていうのは気分であって裏でやる計算だから表には現れない.
一方その計算の結果として表である値を返すときはモナドにその型が入る.
IOに限らずモナドの型 M t というのは
裏である計算をして表でtを返すことを表している.
モナドの定義はその裏の計算を定義しており
一種のメタレベルの記述と見なせる.
だから状態とかインタプリタの例がよく出てくるわけ.
ちなみにHaskellの()は値がないわけじゃなく一つしか値がない型
を表している.ただその値は自明なのでいちいち書かないだけ.つまり上で,
ある値を返すときと書いたが,関数型だから実は必ず値を返している.

469 :466:01/10/25 23:43
つか、d も渡してるし…
> f :: a -> b -> c -> d -> e
に訂正

470 :デフォルトの名無しさん:01/10/25 23:48
 この職って会社のどんな事に役立ってるのですか?
まだ社会人ではないのでまったく想像できません。
ソフトってものはどんなものなのか・・・・・?
それが何の役に立つか何を作っているのか・・・・・?
みなさん教えてください。

471 :デフォルトの名無しさん:01/10/25 23:51
>>466
なるほど、言われてる意味がわかりました。
f::a->b->c->d
(((f a) b) c)
(f a)も((f a) b)も関数ですね。
(f a)::b->c->d
((f a) b)::c->d
ということね。
でも実際は(((f a) b) c)と書くとエラーよね。
高階関数を使えるというのがHaskell。lispは
高階関数は使えない?

472 :デフォルトの名無しさん:01/10/25 23:53
>>467
MLやHaskellで、多引数っぽい関数を書くのに
a->b->c->dみたいにカリー化するのと、
(a,b,c)->dみたいにデカルト積を使う流儀とあるよね。

Haskell: f a b c
Lisp: (((f a) b) c)

Haskell: f(a,b,c)
Lisp: (f a b c)

って感じでは?

473 :472:01/10/25 23:54
>>467 じゃなくて >>468 でした。

474 :デフォルトの名無しさん:01/10/25 23:56
>>471
LispだとエラーだけどSchemeだとエラーにならない。
Lispだと(funcall (funcall (funcall f a) b) c)。欝。

475 :デフォルトの名無しさん:01/10/25 23:59
>>471
そんなことないです。
(define (f a b c)
<code>)

(define (f a)
(lambda (b)
(lambda (c)
<code>)))
で curried 関数の出来上がり。

476 :デフォルトの名無しさん:01/10/26 00:02
って、Lisp は高階関数使えないのか…?
scheme しか知らん…。

477 :デフォルトの名無しさん:01/10/26 00:39
そういえば、いまだにgetCharが参照透明性を失ってない理由がわからない。
IO 'a'とIO 'b'は別の値ということで良いんですか?
別の値なのに、参照透明性を失ってないということなんですか?

478 :デフォルトの名無しさん:01/10/26 00:49
>>477
http://piza2.2ch.net/test/read.cgi/tech/996131288/248-263
これの続き?

479 :デフォルトの名無しさん:01/10/26 00:58
>>477
「getCharを呼ぶとCharが返ってくる」と思うと副作用に見えるかも知れない。
この解釈は間違い。

World型の値w(プログラマには見えないし触れない)があるとして、
(getChar w)を計算した結果、「状態が変わったw」と文字が得られる。

do
c<-getChar
putChar c

の実行を図にするとこんな感じ。

        World
         ↓
getChar  → コマンド → cの値
         ↓
putChar c → コマンド
         ↓
       変化したWorld

式で書くと
let (c,w2)=(getChar w)
in ((putChar c) w2)
みたいな感じ。

480 :デフォルトの名無しさん:01/10/26 01:45
>>479
つまり、見えない「w」という引数が省略されてるって事か?
「getChar」と書いてあるのだが、実は「getChar w」だった
というような。

481 :デフォルトの名無しさん:01/10/26 01:49
>>480
気分としてはそういうこと。
wはプログラマからは決して見えない
(ように設計してあるものをモナドという)。

482 :デフォルトの名無しさん:01/10/26 02:57
納得行かんなあ。副作用が無いんじゃなくて、副作用の部分を
書いてないんでは?
プログラムが未完成で、実行時に補完してるのか?

483 :デフォルトの名無しさん:01/10/26 03:18
>>482
まあ「副作用の部分を書いてない」といえばその通りだが...

例えば配列aのn番目にvを代入するのに、
set_array :: Array a->Int->a->Array a
という関数があるとして、

let a2 = set_array a n v
in
...
set_arrayが「変更された後のa」をa2として返すものとする。
これは参照の透明性を何ら損なわないよね? ただし、破壊的に
代入はできない。aを(少なくとも変更部分だけ)コピーして
おかなければならない。

ここで、「set_arrayが値を返した後は、古いaが使われることはない
(古いaの値を見ているやつは誰もいない)」と保証できたとする。

すると、わざわざコピーしなくても、上書きしてしまっても、
誰も副作用に気が付かない。つまり、コピーしても
上書きしても意味としては同じことになる。

「Worldへの参照が、必ず1個所しか存在しない」ことを保証する
ように工夫したのがモナド。純粋に関数的に解釈するなら、
「putCharするごとにWorldがコピーされる」と思えば良い。
ただし、実際には副作用を使っても、絶対に誰も違いに気が付かない。

484 :デフォルトの名無しさん:01/10/26 03:33
>>483
ということは、モナドを返す関数は、引数が省略されてる特別な関数だと
いうことになるわけ?
Worldを参照してそれを表記では省略しなくちゃいけないのだから、
普通の関数とは働きが違う。
働きが同じだとするとWorldの参照が副作用になってしまう。
つまり、モナドクラスはただのクラスじゃなくてなにか特別な
意味を持つクラスだとしなければつじつまが合わない。

485 :デフォルトの名無しさん:01/10/26 03:51
ライプニッツ入門みたいにも読めるこのスレ大好き!

486 :デフォルトの名無しさん:01/10/26 03:56
>>484
monad と IO を区別しようよ。

487 :デフォルトの名無しさん:01/10/26 04:15
>>484
別に特別というわけではないよ。
ただの高階関数。何も省略なんかしていない。
do以外は、特別な文法を加えたわけでもない。

引数を一部しか与えないなんて、Haskellでは普通の話。

また、Worldという型が直接は触れなくて、IO a
を通してしか操作できない、というのも普通の
抽象データ型。良くある話。

参照が副作用になるってどういう意味?

488 :デフォルトの名無しさん:01/10/26 04:21
>>486
別にmonadの例としてIOを語ってもいいんじゃない?
IOはMonadのinstanceなんだし。

489 :デフォルトの名無しさん:01/10/26 04:34
>>484
何も省略してないという意味は、
「Main.mainにWorldを引数として与えるのは
システムの仕事。プログラマがmainを呼び出したりは
しない。」と言う意味。
Cで、mainに引数を与えて呼び出すのが
システムの仕事であるのと同様。

490 :デフォルトの名無しさん:01/10/26 06:04
もしかしてgetCharの返す値って「入力した一文字を返すと
いう処理」そのもの(マシンレベルでいえば入力した一文字
を返すという処理を行なう機械語列)のこと?それなら
「意図」も腑に落ちるのだけれど。外してる?

491 :490:01/10/26 06:56
補足
処理そのものと解釈すれば
>>= および return を支配している法則
return a >>= k = k a
は「aが返されてそれに対してkすることはaをkすることに等しい」
m >>= return = m
は「mしてreturnすることはmすることに等しい」
と読めるのだけれど。

492 :司馬:01/10/26 13:04
おお,話が進んでいる.
>>490
そう.裏で実行される計算を返す.それが(裏で)実行されるのは>>=のとき.
ユーザ定義でないモナドであればマシン語レベルと言ってもよい.

493 :デフォルトの名無しさん:01/10/26 13:16
>>477
IO Char という型はありますが、IO 'a' や IO 'b' という値(データ)
はないのでは。。。

494 :デフォルトの名無しさん:01/10/26 15:52
>>493
でも、Charという型には'a'っていう値があるんじゃないの?

495 :デフォルトの名無しさん:01/10/26 15:55
>>487>>489
でもWorldという値はどこにも定義されてないよね?
やっぱりそういうどこでも定義されてない裏の値みたいなのを使うのは
副作用なのでは?

496 :デフォルトの名無しさん:01/10/26 16:02
自動詞の暗黙の目的語としてのWorld(むちゃくちゃかも。藁)

497 :デフォルトの名無しさん:01/10/26 16:20
>>495
言いたいことが良くわからない。何がどう副作用なの?
IntやCharの本体の定義も無いと思うが?

498 :デフォルトの名無しさん:01/10/26 17:07
>>494
data Foo Char = Foo (Char -> Int)
としたら、
Foo Char という型はあっても、Foo 'a' という値はないのでは。。。
型構築子とデータ構築子とが混同されているような気がしたもんで。。。

499 :デフォルトの名無しさん:01/10/26 17:50
>>497
IntやCharは型でしょ?
Worldは実際の変数でしょ。
だから、その変数の定義が無いと値が決定できないと思うんだけど。
外部から取得したことになっちゃわない?

500 :デフォルトの名無しさん:01/10/26 18:09
>>499
World型って言っとるやん。
それに、実際には直接出てこないんだからさ。
CでFILE*使ってもデバイスドライバに関するデータが
プログラム中に出てこないのと同じ。

501 :デフォルトの名無しさん:01/10/26 18:11
こんな例はどうだろう。

C言語でRobotをコントロールする。

このRobotには、例えばforward(前進),turn(回転)などのコマンドが
使えるとする。

roboMainという配列に、
char *roboMain[] = { "turn 45", "forward 10", ...};
のように書いておくと、Robotがこれを読み取って実行するものとする。
Cの世界では全く副作用は起きていない。

しかし、これだとRobotからの値を受け取ることができない。
また、Robotの動きを実行時に変えることもできない。

なので、配列に入れるのではなくて、lazyなリスト構造にしよう。
struct roboProgram {
 command (*command_generator)(void);
 struct roboProgram *(next_command)(int arg);
};

commandは(まあchar*でも良いのだが)Robotへのコマンドを表すデータ。
command_generatorはcommandを生成する関数。
next_commandはプログラムの続きを生成する関数。

関数 make_program(command (*com_gene)(void), struct roboProgram (*next)(int));
で、リスト構造が作れるとしよう。

struct roboProgram *roboMain()
{
 return make_program(turn_45, step2);
}

command turn_45(void) { return turn(45); }
struct roboProgram *step2(int ignore)
{
 return make_program(forward_10, step3);
}

command forward_10(void) { return forward(10); }
struct roboProgram *step3(int ignore)
{
 return make_program(get_x_pos, step4);
}

struct roboProgram *step4(int x_pos)
{
 return make_program(turn(x_pos / 2), robo_stop);
}

#しかしCでlazyなリスト作るって面倒だな...

上で、forward(10)やturn(45)を実行したときにRobotが動くわけじゃない。
"forward 10"とか"turn 45"とかいう「コマンド」を返すだけ。
同様に、get_x_posは常に"get_x_pos"という同じコマンド値を返す。

さあ、どこに副作用がある?(いやsprintfは副作用だけどさ^_^;)

502 :デフォルトの名無しさん:01/10/26 18:12
>>500
World型といっても、実際の値があってそれを参照してるよね?
だって、状況によって、モナドが返す値が違うんでしょ?
つまり、それは値を参照して、その値によって返す値を変えてるってことでしょ?
外部から値を参照してるようにしか見えないけど。

503 :デフォルトの名無しさん:01/10/26 18:23
>>502
値はオンナジだよ。

504 :デフォルトの名無しさん:01/10/26 18:24
>>502
もっと具体的に言って?
どこでWorld型の値を参照してて、
どこで副作用が起きてるように見えるの?

もちろん裏では副作用は起きてるわけだけど、
Haskellの世界では全く見えないはずだが。

ストリーム使ったI/Oや継続使ったI/Oでも、
副作用が単に隠されてるだけなのは同じだよね。

505 :デフォルトの名無しさん:01/10/26 18:32
>>504
たとえば、getCharの例を出すと、'getChar'と書いてある所で、'getChar w'を
実行してるかのようにWorld型の変数wを参照してるというのが今までの
説明だよね?
すると、この変数wの中味というのは、外部から与えられた値になると
思うんだけど、このように内容がころころ変わる変数は副作用に思える。

506 :490:01/10/26 18:38
>>492
おー、合ってたか、うれしい。
入出力の章に書いてある
|アクションは式言語のHaskellでは呼出すのではなく定義する
|ものです。アクションの定義を評価することでは、実際のアク
|ションは起こりません。むしろ、アクションは、ここまで考え
|てきた式の評価というものの外側で起こることです
の「アクション」が「処理そのもの」にあたるのだな。

直接触っちゃいけないもの(IOの場合は副作用の起こる処理)
をモナドで包むのね。モナドがコンテナというのはそういうこと
か。Maybeがモナドな理由もこれでわかった。(Maybeは副作用と
は関係ないけど)
んで、直接触っちゃいけないものに触れたものはモナドの演算で
感染していって感染した部分は最小限のモナドで包まれていくと
いうことか。モナドなんとなくわかったよ。
こんな簡単な話だったのか。

507 :デフォルトの名無しさん:01/10/26 18:49
>>505
ちゃうよ。getCharと書いてあるところでは
getCharの値(いつも同じコマンド)が返るだけ。

そのコマンドにwを与えて呼び出すのはシステムの仕事。
当然、毎回異なる引数が与えられるから、毎回異なる値が返る。

getChar wを呼び出した結果、World型の値w2が得られたとする。
呼び出す前のwは2度と使われない。

>>501 を見ても分からない?

508 :デフォルトの名無しさん:01/10/26 18:51
getCharと書かれた部分は毎回同じ値を返すのか?
yesかnoで答えてくれ。

509 :デフォルトの名無しさん:01/10/26 18:54
>>507
>>501を見ても、実行の仕方が書いてないのでなんともいえない。

510 :490,506:01/10/26 18:54
>>507
どこがちがうの?501も507も俺の思ってるとおりのこと言ってるよ

511 :デフォルトの名無しさん:01/10/26 18:56
>>505
>>479 をもっかい見てみたら?

getCharが2回続けて出てきたとして、
do
 c1<-getChar
 c2<-getChar
 ...
実行時に起きることの気分は、
let (c1, w1) = (getChar w0)
in
 let (c2, w2) = (getChar w1)
 in
 ...
みたいな感じだよ?
どの行が副作用に見える?

512 :デフォルトの名無しさん:01/10/26 18:58
>>511
w1とか、w2が省略されてるところが副作用に見える。
省略してる値がころころ変わってるから。

513 :デフォルトの名無しさん:01/10/26 18:58
>>508
yes。毎回同じ値を返す。Haskellだから当然。

>>509-510
501のCプログラムのどの行で副作用が起きてる?

514 :490,506:01/10/26 18:58
あ、ごめん。505にいってたのか

515 :デフォルトの名無しさん:01/10/26 18:58
>>508
yes

516 :デフォルトの名無しさん:01/10/26 18:59
>>513
501のプログラムは決められたことを決められたように実行してる
だけでは?
IOのように動的に値が変わってない。

517 :デフォルトの名無しさん:01/10/26 19:01
じゃあ、
a=1;
a=2;
と同じことをモナドで書くとどうなるの?
どうして副作用が消えるの?

518 :デフォルトの名無しさん:01/10/26 19:04
>>512
あー、そうか。

ええっと、
do
 c1<-getChar
 c2<-getChar

let (c1, w1) = (getChar w0)
in
 let (c2, w2) = (getChar w1)
 in
 ...
が「同じだ」と言ってるわけではないぞ。

do
 c1<-getChar
 c2<-getChar
で「コマンド列」というlazy listが作られる。
このときにはまだwを引数にして呼び出したりしないし、
副作用も起きない。

そのコマンドを1個1個呼び出していくプログラムはシステム側にある。

Cの例で言えば、Robotがlazy listをたぐりながらコマンドを1つずつ
得て、コマンドを実行していく。その過程では当然副作用が起きる。

でも、>>501 で書いたCのプログラムでコマンド列を作っている部分
には副作用なんかないだろ?

519 :デフォルトの名無しさん:01/10/26 19:05
>>517
書けない。
副作用はないので、『副作用が消える』ことはない。

520 :デフォルトの名無しさん:01/10/26 19:13
>>518
なるほど。副作用の無いプログラムが、副作用のあるプログラムを
作り出してるのか。
作り出すところまでが、Haskellということになるね。
また、何かわからないことがあったら質問します。

521 :デフォルトの名無しさん:01/10/26 19:18
>>516
x_posの値は動的に得て、forwardの距離を変えているが...
Robotの位置が最初不定だとすれば、毎回違う動作をするはず。
別にここにif文入れて、「右にturnするか左にturnするか」とか
やってもよいよ。それでも副作用は起きない。

>>517
<-演算子のことを言ってるなら、
左辺は毎回新たに定義される変数だよ。

do
 a<-getChar
 a<-getChar
 ...
は、
 getChar >>= \a->(getChar >>= \a->...)
と同じ。

Monadicにやるなら、こんな感じだろう。

instance Monad Var
...

define_var :: String->a->Var ()
 -- 変数を宣言し、初期値を与える
set_var :: String->a->Var ()
 -- 変数に値を代入する
ref_var :: String->Var a
 -- 変数の値を取り出す。

...
  define_var "my_var" 1 >>
  ref_var "my_var" >>= \a
  ->set_var "my_var" (a + 1)
  ...

define_var, set_var, ref_varは単に「定義しろ」「代入しろ」「参照しろ」
というコマンドを返すだけだから、副作用はない。そのコマンドを解釈実行
するプログラムにはあるかもしらんが。(副作用使う実装なら、Haskell自身
ではもちろん書けない。)

522 :デフォルトの名無しさん:01/10/26 19:29
このスレ熱心な良スレだね。

523 :デフォルトの名無しさん:01/10/26 19:40
名スレの予感

184 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)