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

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

純粋関数型言語Concurent Clean

1 :デフォルトの名無しさん:04/02/01 18:55

純粋関数型言語Cleanに関するスレッドです。
関数型には珍しくIDEと、IO,Gameライブラリが標準でついてきます。


関連リンク
本家
http://www.cs.kun.nl/~clean/
日本語ドキュメントなど
http://sky.zero.ad.jp/~zaa54437/programming/clean/

111 :デフォルトの名無しさん:04/05/27 12:46
大体そだよ。

112 :デフォルトの名無しさん:04/05/27 13:06
つか、グラフを使用した説明はわかりやすいと思うけれども。

113 :デフォルトの名無しさん:04/07/11 04:25
せいうちん

114 :名無しさん@そうだ選挙に行こう:04/07/11 18:17
kinnikuman 2 sei?

115 :デフォルトの名無しさん:04/08/03 01:56
>>104
Mercuryという言語で使える。
http://www.cs.mu.oz.au/mercury

#Clean好きで来てみたら寂しいスレだ(′・ω・`)。
#現在Cleanの一意性型の論文読んるけどわかったようなわからんような。


116 :デフォルトの名無しさん:04/08/29 15:23
Cleanで書かれたテトリスのソースはどこかにないでしょうか?
古いバージョンに付いていたそうですが、今のには無さそうなので・・


117 :デフォルトの名無しさん:04/09/15 17:55:52
if c (fwritec 'a' file) (fwritec 'b' file)

は大丈夫なのに

MyIf True t e = t
MyIf False t e = e
MyIf c (fwritec 'a' file) (fwritec 'b' file)

はだめなのか。

118 :デフォルトの名無しさん:04/09/19 03:40:16
>>117
MyIfについては、一意型の*Fileオブジェクトへの参照数が2になるのがエラーの原因のはず。
このあたりに説明があったと思う:http://sky.zero.ad.jp/~zaa54437/programming/clean/LanguageReport21/Chap9.html

ifは言語組み込みの機能だから、特別扱いだと思う。StdEnv探しても関数の定義がないし。
(_system.abcにifの定義らしき記述があるけど・・・読める人いたら解説きぼん)

言語組み込みのifに相当するMyIfは、通常の関数として書けないような気がするけど
実際のところはどうなんでしょうか>詳しい人


119 :デフォルトの名無しさん:04/09/24 18:13:14
>>117
MyIf b t e =
| b = t
| otherwise = e
処理系が手元にないんで試せないけど、これでもダメかね?
tが評価される時はeがゴミなのでfileへの参照は1になると思うんだが。

120 :デフォルトの名無しさん:04/09/24 18:59:43
要するにAlternativeに書けってことだな。

121 :デフォルトの名無しさん:04/09/24 23:51:36
>>119
ダメですた。

つーか、
MyIf b t e = if b t e
でもダメ。


122 :デフォルトの名無しさん:04/09/25 01:17:12
MyIf b (fwritec 'a' file) (fwritec 'b' file)の時点で、fileへの参照数が2だと認識されている模様。

まあMyIfを使わず、素直にガードで分岐すれば動作するんだけどね。
ガードやcaseなら、ちゃんとAlternativeだと見なしてくれる。
WriteAorB b file
| b = fwritec 'a' file
= fwritec 'b' file


123 :デフォルトの名無しさん:04/09/26 19:08:00
なんかこの言語サンプル見ても意味不明なのがすごいです
構文が抽象化されすぎて余計わかりにくい感じがするのですが

124 :デフォルトの名無しさん:04/09/26 19:59:48
コンピュータに量はおまかせを……

125 :デフォルトの名無しさん:04/09/26 23:39:43
Haskellとあんま変わんないとおもうけど。
IOからまなきゃ

126 :デフォルトの名無しさん:04/09/28 13:06:25
>>122
分岐(if, case, ガード)が陽に見えているところでしか
一意性解析していないということか。

MyIfが使えるようにするには、自分で型に一意性注釈を
書かなければならないのだろうが、分岐のような
「いくつかの引数のうちどれか一つしか評価しない」というような
ことを型レベルで表現するのは無理だから、やっぱできないのかな。

127 :デフォルトの名無しさん:04/09/29 22:43:40
んなもんLISPみたいにquoteがないと作れるわけない

128 :デフォルトの名無しさん:04/09/30 00:50:39
一意性解析ってどうやるんだろ。ちょっと考えてみた感じだと

関数はパターンマッチングによる場合分けによって定義されるとする。
その場合の単純な一意性解析の戦略を考えてみると関数の定義が以下の形
f x = g1 a1
f x = g2 a2
...
(x, a1, a2, ... は引数の列)
だった場合、最外簡略を仮定すると引数は2つのグループに分けられる(両方に属するものもあるか)。
つまりどの場合分けを採用するかを決める際に評価され得る引数と、その後に評価されうる引数である。
前者は引数で変数以外のパターンが使われているもの、後者は右辺で使われているものである。
前者の集合をP_fとし、後者の集合をS_f_1, S_f_2, ...とする。(fは自明なときは省略)
例えば
MyIf True t e = t
MyIf False t e = e
の場合P_MyIf = {1番目の引数}, S_MyIf_1 = {2番目の引数}, S_MyIf_2 = {3番目の引数}となる。
このときある変数が一意である条件は
それがPに高々1回だけ現れ、Sには現れない。
それが各S_iについて高々1回だけ現れ、Pには現れない。
のどちらかとなる。
これで単純な場合は大丈夫だけど
MyIf c t e = if c t e
とするとP = {}, S_1 = {c, t, e}となって上手く行かない。
そのためには
f x = g (h1 a1) (h2 a2) ...
という形を考えてgやh1などのP, Sも考慮に入れればOK?
それで十分なのか、それができるのかはもうちょっと考えてみないとわからない。

おしえてエライ人。

129 :デフォルトの名無しさん:04/10/26 02:32:30
UNIX環境でつかってる人いる?

130 :デフォルトの名無しさん:04/10/26 21:40:24
バイナリ版を試してみようとしたけど、xviewがないと動かない……。
面倒なのでその先はまだやってないっす。

FreeBSD で動かしたくてソースコードもダウンロードしたけど、アセンブリばっ
かしなのでかなり無理っぽい。っていうかどういう風にビルドすればいいのか
ぜんぜんわからない。


131 :デフォルトの名無しさん:04/11/05 13:48:35
そんじゃ最初っから話にならないじゃん(w

132 :デフォルトの名無しさん:04/11/05 18:50:51
開発環境込みの環境だからねえ。
GUI な開発環境なし版が欲しい。

ただ、普通の Linux とか Solaris なら動くんじゃないの?

133 :デフォルトの名無しさん:04/11/10 13:02:17
コンソールでやるにはどうしたら良いんだ?ってのがMLで話題になってたな、随分前

134 :デフォルトの名無しさん:04/11/22 20:48:55
さすがにこれを仕事で使う勇気のある奴はまだ日本にはいないだろうな

135 :デフォルトの名無しさん:04/11/23 01:26:28
一応開発元は実用言語目指してるんだけどねぇ。
今開発って続いてるの?

136 :デフォルトの名無しさん:04/11/24 10:42:39
開発というより研究は続いている

137 :デフォルトの名無しさん:04/12/15 20:43:51
下のがエラーになる理由がわからん

Length :: [a] -> Int
Length = foldr (¥x -> (+) 1) 0

138 :デフォルトの名無しさん:04/12/15 23:30:00
型が違うよー
Lengthは引数を持たず(アリティ0)、リスト[a]をIntに変換する関数を返すので

Length :: ([a] -> Int)

でたぶん通る。

139 :デフォルトの名無しさん:04/12/22 21:13:21
>>138
おおサンクス
型が違ってたのか。Lengthの定義がおかしいのかと思ってたよ。

最近関数型言語の勉強はじめたんだが、楽しすぎるな。
「プログラミング言語は思考の増幅器である」って昔誰かが言ってたが
まさにそんな感じ。脳汁出まくりですよ

140 :デフォルトの名無しさん:05/01/21 19:21:00
新バージョンが出る予感

141 :デフォルトの名無しさん:05/03/15 21:08:05
http://www.cs.ru.nl/~clean/Recent_Latest_News/body_recent_latest_news.html
によると、一昨年の10月31日の 2.1.0 から更新されてない様だが、新しいのあるの?

142 :デフォルトの名無しさん:2005/05/06(金) 16:08:55
Clean I/O と Haskel monadic I/Oの違いを教えてください。

143 :デフォルトの名無しさん:2005/05/14(土) 00:12:25
唐揚げ

144 :デフォルトの名無しさん:2005/05/14(土) 00:12:59
唐揚げ

145 :デフォルトの名無しさん:2005/07/16(土) 14:20:22
新バージョン出てるよ

146 : :2005/07/18(月) 21:05:13
May 31, 2005
Clean 2.1.1 is released for Windows, MacOS X, Linux, and Solaris.
This release contains bug fixes and new features, to wit:
 + Libraries for Windows: GAST, GECs, Hilde, Parser
 + Foreign exports
 + Improved redirected standard input/output
 + Let in comprehensions
 + Code generator optimisations

147 :デフォルトの名無しさん:2005/07/19(火) 08:33:13
ここもdylanスレぐらい寂れてんな
Cleanが話題にならない理由として考えられるのは
基本概念が複雑なことだな
異質すぎて何が効率よいとかが判断できない


148 :デフォルトの名無しさん:2005/07/19(火) 12:46:18
複雑じゃないよ、異質ではあるが

149 :デフォルトの名無しさん:2005/07/19(火) 20:25:19
どうでも良い事かもしれんが、ダウンロードにレジストレーションが必要なのは面倒。
ライセンスも分かりにくい。自分が書いたコードはライセンス汚染を受けるの?

150 :デフォルトの名無しさん:2005/07/19(火) 20:48:23
>>149
非商用の場合はLGPL、商用の場合は要問合せ。
そもそも、registしなくてもダウンロードできるし。

151 :デフォルトの名無しさん:2005/07/19(火) 21:15:51
>>150
static なライブラリを作るのか知りたかったんだけど、レジスト不要なら自分で試してみます。
サンクス。

static でもソース公開の義務がないのは知ってるけど、ちょっと面倒だね。

152 :デフォルトの名無しさん:2005/07/20(水) 20:33:06
>>148
異質ってことは、複雑かどうかもわからんてことよw
難解だよな

153 :デフォルトの名無しさん:2005/08/06(土) 12:24:17
Concurrent Clean 日本語化プロジェクト 期待あげ
ttp://www.geocities.jp/lethevert/softwares/clean/localize.html

154 :デフォルトの名無しさん:2005/08/06(土) 12:52:50
ここ見てるか知らないけど
がんばれよー


155 :デフォルトの名無しさん:2005/08/06(土) 19:36:04
GUIライブラリまで揃ってるのに…もう少し人気出ないもんかね

156 :デフォルトの名無しさん:2005/08/06(土) 20:14:56
人気が出る要素がまるでないからな

157 :デフォルトの名無しさん:2005/08/07(日) 00:09:29
せめてHaskell程度には…

158 :デフォルトの名無しさん:2005/08/07(日) 14:50:44
ベンチマークとか
他言語とのコードの比較表とか
そういったもので優位性というか、
どんだけ違うか示していくというのはどうか


159 :デフォルトの名無しさん:2005/08/08(月) 14:13:59
>>156
( ´_ゝ`)フーン
「まるでない」と言い切れるほど詳しくご存知なんですね。

160 :デフォルトの名無しさん:2005/08/10(水) 23:11:26
たぶんClean理解してる奴日本全国数えても20人いなさそう。

161 :デフォルトの名無しさん:2005/08/25(木) 21:50:11
Linuxでやってみました。
CUIは問題無く動きました。
GUIはXView無しでもWINE使って、
Hello World 程度を動かせました。
Wineでもいいから一通り動いて、
1.3のlibraryも使えて、
Emacsのclean-modeがhaskell-mode並に使えれば…と思います。


162 :勉強中:2005/09/07(水) 22:28:59
HaskellよりCleanの方が有望に見える。


163 :デフォルトの名無しさん:2005/09/07(水) 23:42:54
>>162
詳しく

164 :デフォルトの名無しさん:2005/09/08(木) 00:11:17
土方プログラマやりながら勉強してるから、
勉強終わるまでちょっとまって。


165 :デフォルトの名無しさん:2005/09/11(日) 21:05:30
Haskellはコンパイル遅杉

166 :名無しさん@そうだ選挙に行こう:2005/09/11(日) 23:03:09
>>165
ここはCleanのスレですが

167 :デフォルトの名無しさん:2005/09/23(金) 10:59:05
Clean は完璧主義のデレツン言語。
Haskell は他言語で1文字でも短く書けるコードがありましたら、
お申し出下さい言語。


168 :デフォルトの名無しさん:2005/09/25(日) 03:21:36
language shootoutのfannkuchenで遊んでみました
// (setq compile-command "clm -b -nt f && time ./a.out")
module f
import StdEnv

permutations [] = [[]]
permutations [x:xs] = [zs \\ ys <- permutations xs, zs <- interleave x ys ]

interleave x [] = [[x]]
interleave x [y:ys] = [[x:y:ys] : [[y:z]\\ z <- interleave x ys]]

flop [1:ys] = 0
flop lis = 1+ flop (revAt (hd lis) [] lis)
where revAt 0 fr bk = fr++bk
revAt _ fr []= fr
revAt n fr [x:xs] = revAt (n-1) [x:fr] xs

Start = "Pfannkuchen(9)=" +++ toString (maxList [flop x \\ x<- (permutations [1..9])]) +++""


169 :デフォルトの名無しさん:2005/09/25(日) 04:14:55
意味不明度120%言語

170 :デフォルトの名無しさん:2005/09/25(日) 18:29:33
>>169
言語のせいにするなってw

171 :勉強中:2005/09/28(水) 23:37:02
過疎。
一意性型付けは一部で型を自分で指定しないといけないのがキツイ
ここらへんは CLASが参考になりそう。
// update使うともう少しよさげ
arraySwap ar i j
#(v_i,ar) = ar![i]
#(v_j,ar) = ar![j]
= {ar & [i]=v_j,[j] =v_i}

arrayReverse ar a z
| a >= z = ar
= arrayReverse (arraySwap ar a z) (a + 1) (z - 1)

arrayCopy:: !*{#Int} -> *(*{#Int}, *{#Int})
arrayCopy ar
#(sz,ar)=usize ar
#(ar_0,ar)=ar![0]
= arrayCopyRange ar (createArray sz ar_0) 0 (sz-1)

arrayCopyRange:: !*{#Int} !*{#Int} !Int !Int -> *(*{#Int},*{#Int})
arrayCopyRange ar ar2 i j
| i > j = (ar,ar2)
#(v_i,ar) = ar![i]
= arrayCopyRange ar {ar2 & [i]=v_i} (i+1) j

172 :デフォルトの名無しさん:2005/09/30(金) 00:06:48
Cleanの編集モードだけど clean-mode より haskell-modeの方が書きやすいと思った。

173 :デフォルトの名無しさん:2005/10/02(日) 01:10:08
countFlips:: !Int !*{#Int} -> (Int,*{#Int})
countFlips acc perm
# (p_0, perm) = perm![0]
| p_0 == 1 = (acc,perm)
= countFlips (1+acc) (arrayReverse perm 0 (p_0-1))
successor:: !*{#Int} -> (Bool,*{#Int})
successor perm
# (n , perm) = usize perm
# (i , perm) = lp1 (n- 2) perm
| i == -1 = (False, perm)
# (ith, perm) = perm![i]
# (j,perm) = lp2 (n - 1) ith perm
# perm = arrayReverse (arraySwap perm i j) (i + 1) (n-1)
= (True , perm)
where
lp1:: !Int !*{#Int} -> (Int, *{#Int})
lp1 i perm
| i < 0= (-1 , perm)
# (plus,perm) = perm![i+1]
# (val,perm) = perm![i]
| plus > val = (i, perm)
= lp1 (i-1) perm
lp2:: !Int !Int !*{#Int} -> (Int, *{#Int})
lp2 j ith perm
# (val_j , perm) = perm![j]
| (val_j > ith) = (j,perm)
= lp2 (j-1) ith perm


174 :デフォルトの名無しさん:2005/10/02(日) 01:13:23
fannkuch n = loop 0 {y\\ y <- [2,1] ++[3..n]} (createArray n 0)
where
loop::!Int !*{#Int} !*{#Int} ->Int
loop f pi pi2
# (pi, pi2) = arrayCopyRange pi pi2 0 (n-1)
# (c , pi2) = countFlips 0 pi2
# next = max c f
# (suc, pi) = successor pi
| suc = loop next pi pi2
= next
Start = fannkuch 9
// 全て型を付けても Cの1.5倍以上遅い orz


175 :デフォルトの名無しさん:2005/10/02(日) 23:34:16
pure Cleanでgccより速くなりました。比較対象はdebian gcc 4.0.1
gcc -pipe -Wall -O3 -fomit-frame-pointer -funroll-loops f.c -o f.gcc_run
time ./a.out 9 && time ./ f.gcc_run #Cは某所にこれ追加 > p[0]=2;p[1]=1;
real0m0.181s # clean
real0m0.201s # gcc
//clm -h 450k -b -nt -I /home/my/share/lib/clean -I /home/lib/StdLib
// -I /home/my/clean/lib/ArgEnv/ -l /home/my/clean/lib/ArgEnv/ArgEnvC.o
// fannkuch && time ./a.out 9"
module fannkuch
import StdEnv, StdMaybe, MyUtility, MyArray
countFlips:: !Int !*{#Int} -> (Int,*{#Int})
countFlips acc perm #! (p_0, perm) = perm![0]
| p_0 == 1 = (acc,perm)
= countFlips (1+acc) (arrayReverse perm 0 p_0)
fannkuch n = fannkuch` 0 {y\\ y <- [2,1] ++[3..n]} (createArray n 0)
where
fannkuch`::!Int !*{#Int} !*{#Int} ->Int
fannkuch` f org cpy
#! (org,cpy) = arrayCopyn org cpy n
#! (c,cpy) = countFlips 0 cpy
= case (successorPermutaion n org) of
Just org = fannkuch` (max c f) org cpy
Nothing = max c f
Start ="pf("+++ arg1+++")="+++toString (fannkuch (toInt arg1)) +++ ";"


176 :デフォルトの名無しさん:2005/10/02(日) 23:40:08
arraySwap:: !*{#Int} !Int !Int -> *{#Int}
arrayReverse ar a z :== arrayReverse` ar a (z-1)
// arrayReverse 概略 araySwap inline化
arrayCopyn ar ar2 n :== arrayCopyn` ar ar2 (n-1)
where arrayCopyn`:: !*{#Int} !*{#Int} !Int-> (*{#Int},*{#Int})
arrayCopyn` ar ar2 -1 = (ar,ar2)
arrayCopyn` ar ar2 i
#! (v_i,ar) = ar![i]
= arrayCopyn` ar {ar2 & [i]=v_i} (i-1)
successorPermutaion n perm :== successor` (n-2) perm
where successor`:: !Int !*{#Int} -> (Maybe *{#Int})
successor` i perm
| i < 0= Nothing
#! (plus,perm) = perm![i+1]
#! (val,perm) = perm![i]
| plus > val#! (ith,perm) = perm![i]
#! (j, perm) = lp2 (n - 1) ith perm
#!perm = arrayReverse (arraySwap perm i j) (i + 1) n
= Just perm
= successor` (i-1) perm
lp2:: !Int !Int !*{#Int} -> (Int, *{#Int})
lp2 j ith perm#! (val_j , perm) = perm![j]
| (val_j > ith) = (j,perm)
= lp2 (j-1) ith perm
//これを動かしたい人はいろいろ組合わせて下さい。
// *組*を作成しなければ、無駄なメモリ消費量を抑えられるはず。

177 :デフォルトの名無しさん:2005/10/03(月) 21:42:37
>>176
*組* ってちょっと…
「タプル」でいいんじゃない?

178 :デフォルトの名無しさん:2005/10/03(月) 23:22:07
>>177
助言サンクス

で一応まとめ fannkuch: indexアクセスと整数演算の性能
1 最適化がはまらないとちょっと遅い(はまればC並に最適化できる)
1.1 遅いのは、Clean内部システム?が Lazyでごちゃごちゃ動くため
1.2 関数化無しではLOOPが書ず、inline化されない?ため、いろいろ無駄になる
2 LIST使っても、revAtみたいな展開と内包表現を多用すれば、
3〜5倍の実行時間で済むっぽい。コンパイラの頭が良くなって、
今回の +++が 破壊的な関数で最適化されれば、もっと速いはず (set-cdr!で一発)
3 短くはないが、比較的綺麗な関数単位で書いた割に速い
funnkuch の countFlips, successorPermutaion , maxを外に出せば
uarrayAccumulateWithSuccessor. lp2は (uarrayFindIndexBy (\x->x>ith))
4 ライブラリはかなり少ない

速くするには
A shootout のOCAMLやD言語ではアルゴリズムがこれと少し違うっぽいので真似る
B Cleanの最適化について学ぶ
C 関数一つにまとめて、共有できる変数は共有するとか。
D abc codeを書くとか
//省略部
arraySwap ar i j#! (v_i,ar) = replace ar i 0
#! (v_j,ar) = replace ar j v_i
={ar & [i]=v_j}
今後は目標として、LISP(Scheme)をCleanに翻訳とかやるかも。では、さよーなら。

179 :デフォルトの名無しさん:2005/10/09(日) 03:44:31
有用な関数を置いときます。関数名が怪しげですが。

trimNewline::!String -> String
trimNewline "" = ""
trimNewline str| str. [n-1] == '\n'
| str.[n-2] == '\r' = str % (0, n - 3)
= str % (0, n - 2)
= str
where n = size str

CallWithInputFile:: !String !(*fs -> (a,*fs)) !(*File -> (a, *File)) !*fs -> (a, *fs) | FileSystem fs
CallWithInputFile filename error proc files
#! (ok, f, files) = fopen filename FReadData files
| ok #! (value, f) = proc f
#! (_,files) = fclose f files
= (value, files)
= error files

foldWithReadline:: !(String a-> a) a !*File -> (a, *File)
foldWithReadline proc knil file
#! (end,file) = fend file
| end = (knil, file)
#! (line, file) = freadline file
= foldWithReadline proc (proc (trimNewline line) knil) file


180 :デフォルトの名無しさん:2005/10/09(日) 08:26:13
先生!質問です。
この言語には整数は32bitしかないのでしょうか?64bitは無し?

181 :デフォルトの名無しさん:2005/10/09(日) 09:29:44
せっかくnon-strict関数型言語の標準をhaskellとして定めたのに、方言を作りやがって……
これじゃMLと同じ轍を踏むことになるじゃないか

とSPJが言ってました。

182 :勉強中の人:2005/10/09(日) 14:37:00
>>180
windows版で BigInt、Rational, Complexのライブラリはあるようです。

>>181
バートランド・ラッセルが
「宗教の数は時代の遷移に共なって、指数関数的(対数だったっけ?)に変化する」
とか言ったのに似て、プログラミング言語も人間の頭の中からできたものだから、
ある程度分裂する感じがする。(指数関数的 1- e^(-n*x))
最適化問題として捉えても、研究者じゃない人間が遊んだり、
一部の研究者が触っても問題ないどころか良い事だと思うし。
Privateで工学・政治的な理由に付き合う理由はあまりないと思う。

モナドで包まれない状態が生で触れるためCleanはhaskellの勉強になる。
ただ、generic も モナド もよくわかってないが、
モナドの方が良くできてる感じがする。
他にも hasktags はあるけど、 cleantags はないとかかなり不便。

ちなみに、SPJとか知らんですよ。

183 :180:2005/10/10(月) 05:33:09
>>182
ありがとうございます。
日本語使えるよう頑張ってるヒトいるみたいだし勉強してみようかなぁ...


> ちなみに、SPJとか知らんですよ。 
Simon Peyton-Jonesさんではないかと。Glasgow Haskellの中のヒトかと。

184 :デフォルトの名無しさん:2005/10/10(月) 09:43:14
>>183
茨の道ですよ。多分。

//CallWithInputFile 使い方 (22行)
strStr:: !String !String !Int -> (String, Int)
strStr str1 str2 p=lp p 0
where n = size str1
m = size str2
lp i j| j == m = (str1 %(p,i-m-1) , i-m)
| i == n = (str1 %(p,i-1) , i)
| str1.[i] == str2.[j] = lp (i+1) (j+1)
= lp (i+1) j
stringSplit s c :== reverse (stringSplitAcc s c 0 [])
stringSplitAcc:: !String !String !Int ![String] -> [String]
stringSplitAcc str del i ret
| p==(size str) =[match:ret]
= stringSplitAcc str del (p+1) [match:ret]
where (match,p) = strStr str del i
readCsv line knil :== [stringSplit line ",": knil]
csvReader:: !*File -> ([[String]] , *File)
csvReader file# (s,file) = foldWithReadline readCsv [] file
= (reverse s, file)
errorFunc:: String *fs -> ([[String]], *fs) | FileSystem fs
errorFunc mes files= abort mes
Start:: *World -> ([[String]],*World)
Start world =CallWithInputFile "test.txt" (errorFunc "error") csvReader world


185 :デフォルトの名無しさん:2005/10/10(月) 12:47:07
行数制限が気になって、雑になりました。

>>183 SPJ氏について
サンクス、自分専門ではないもので助かります。

downcase :: !String -> String
downcase str = {toLower x\\x<-:str}
upcase :: !String->String
upcase str = {toUpper x\\x <-:str}

stringJoin:: ![String] !String -> String
stringJoin [x:xs] c = x +++ (join` xs)
where join`:: [String] -> String
join` [] = ""
join` [x:xs] = c +++ x +++ join` xs
stringJoin [] _ = ""

ライブラリはよく吟味した上で一元管理がよさそう


186 :デフォルトの名無しさん:2005/10/11(火) 00:30:37
Linux版でfopenしてもファイルが生成されない。恐いw
readはできたが。


187 :勉強中の人:2005/10/13(木) 22:54:27
ファイルIOその場凌ぎ。
// system_clean.c ヘッダー省略(Linux System系) gcc -O3 -c system_clean.c 
#define CLStr2C(str,name,len) int len=CleanStringLength(str);char name[len+1];\
strcpy(name,CleanStringCharacters(str));name[len]='\0';
int Time () {return (int)time(NULL);} //おまけ
int openWriteClose(CleanString cpath, CleanString cstr) {
CLStr2C(cpath,path,len);
int fd = open(path,O_WRONLY|O_APPEND|O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (!fd) {printf("test");return errno;}
write(fd, (void*)CleanStringCharacters(cstr), CleanStringLength(cstr));
close(fd);return 0;
}
// system_clean.h // htoclean は シンボリックリンクを認識しない様子
Clean (::*State :== Int;)
int Time ();
int openWriteClose(CleanString Path, CleanString cstr);
Clean(Time:: *State -> (Int,*State);openWriteClose:: String String-> Int;)
// test.icl //ヘッダー省略 clm -l system_clean.o
Start :: *World -> (Int,(Int,Int))
Start w = (openWriteClose "test.out" "test", (Time 1)) // open "a+" 755

自分がCleanをやるのは、計算機にパズルを解かせるための道具として
よさそうだと思ったからです。(速い、成功リスト法等)
何でもあり風な tabooSearch とかにも向いてると思う。(配列以外は)


188 :デフォルトの名無しさん:2005/10/25(火) 23:17:03
// haskellの真似 とか調べたことでも書いてみる
foldrWithReadline:: !(String a-> a) a !*File -> (a, *File)
foldrWithReadline proc knil file
#! (end,file) = fend file
| end = (knil, file)
#! (line, file) = freadline file
# (lines , file) = foldrWithReadline proc knil file
= ((proc (trimNewline line) lines), file)
foldrWithReader:: !(*File->(Bool,a,*File)) !(a b->b) b !*File -> (b, *File)
foldrWithReader reader proc knil file
#! (ok, token, file) = reader file
| not ok = (knil, file)
# (tokens , file) = foldrWithReader reader proc knil file
= ((proc token tokens), file)
foldrWithReadChar:: !(Char a-> a) !a !*File -> (a, *File)
foldrWithReadChar x y z = foldrWithReader freadc x y z

readFile :: !String *World -> ([String],*World)
readFile path wld = callWithInputFile path
(\x -> abort ("readFile :: " +++ path ))
(foldrWithReadline (\x y -> [x:y]) []) wld

readFileChar :: !String *World -> ([Char],*World)
readFileChar path wld = callWithInputFile path
(\x -> abort ("readFileChar :: " +++ path))
(foldrWithReadChar (\x y -> [x:y]) []) wld


189 :デフォルトの名無しさん:2005/10/25(火) 23:46:25
// モナディック・スタイル cより悪いってことはない。ここで五分でも他で返せる。
Start = /*runState {a=1,b=2}*/ // struct state= {a=1,b=2};
(fa >>>= \r // r = fa(state);
-> fa >>>= \r2 // r2= fa(state);
-> return (r+r2)) // return r+r2;
{a=1,b=2}

// 何倍も遅いが簡潔に書けるかもしれない
stCond :: ![( a->(Bool,a), a->a )] !a -> a
stCond [] st = st
stCond [(pred,f):xs] st
# (p, st`) = pred st
| p = f st`
= stCond xs st`

//ちょっと便利そうなコード
(++%) infix 4 :: String Int -> String
(++%) st i = st +++ (toString i)

学んだこと:もし、HaskellやCleanの開発で困ったら、
それはきっと、創造力と設計能力と人手が足りないからだ。
(実行速度は遅くなっても創造力でカバーする)
創造力を減らさないためには、純粋関数型的なコーディングは欠かせない。
自分にはそんな能力はないけどw

190 :デフォルトの名無しさん:2005/10/26(水) 00:50:31
追伸: >>>= の演算子
StateMonad はどこかに落ちてるから、find 等を駆使して探したり、
ファイルを一箇所にまとめ grep [sS]tate *.icl とかやって探して下さい。
haskellのように m1 >>>= True -> m2 >>>= \r -> return r とかはできない。

・Hacle (Haskell -> Clean トランスレータ)
生成されるCleanコードは想像以上に汚ないので、あまり使いたくない。
Haskellで書いたコードが運良ければ速くなるという代物。

・elisp
;; interactive を defun。srfi cutみたいにしたいけど面倒なので略 (cutは作ったし)
(defmacro defuni-by-cut (name func &rest args)
`(defun ,name ()
(interactive)
(,func ,@args)))

;; w3mが遅いのでローカルへ置きました。 wget を使いました。
;; どこかの池田さんの有名なページ
(defuni-by-cut clean-doc w3m-find-file "/home/clean/doc/zaa54437/home.htm")
(defuni-by-cut clean-lang w3m-find-file "/home/clean/doc/zaa54437/programming/clean/LanguageReport21/index.html")
(defuni-by-cut clean-obj w3m-find-file "/home/clean/doc/zaa54437/programming/clean/ObjectIOLibrary12/index.html")
(defuni-by-cut clean-book w3m-find-file "/home/clean/doc/zaa54437/programming/clean/CleanBook/index.html")
;; 同様に リファレンスは Haskell のやつ使って 関数が無ければ自分で作るとか。
;; gauche のマニュアルも使えるかもしれない。


191 :デフォルトの名無しさん:2005/10/29(土) 23:11:18
Cleanやる人増えないかな。と考えつつ書いてみる。

// 行列線形代数(一意なし) ちょっと遅い 小さい行列やループが入れば
// octave interpleter よりマシ, Lisp, Haskellより多分マシ
// Blasのwrapperは Linuxでは ccall で配列が渡せなく?失敗 、windowsは面倒で断念
My_degmm_simple :: !Int !Int !Int !{#Real} !{#Real} -> {#Real}
My_degmm_simple an am bm a b
= {inprod (i + dam*an) (am * j + dam) 0.0 \\ j <- [0..dan] , i <- [0..dam]}
where dan = an - 1 //dec an
dam = am - 1
inprod:: !Int !Int !Real -> Real
inprod dam1 amq acc
| dam1 >= 0 =inprod (dam1 - am) (amq - 1) (acc + a.[dam1] * b.[amq])
= acc
// --------------------mat -------------------
::MyMatrix e = !{mat :: !({#} e), row:: !Int, col:: !Int}
::MyRMatrix :== MyMatrix Real

makeMatrix :: !Int !Int !{#Real} -> MyRMatrix
makeMatrix i j mat = {mat=mat,row=i,col=j}

instance + MyRMatrix where
(+) :: !MyRMatrix !MyRMatrix -> MyRMatrix
(+) a=:{mat,row,col} b
= {mat={x+y \\ x <-:mat& y<-:b.mat}, row=row,col=col}


192 :デフォルトの名無しさん:2005/10/29(土) 23:13:54
instance * MyRMatrix where
(*) :: !MyRMatrix !MyRMatrix -> MyRMatrix
(*) a b = {mat=My_degmm_simple a.row a.col b.col a.mat b.mat,
row = a.row, col =b.col}

// transpose
class transpose a :: !a !Int !Int -> a
instance transpose {#Real} where
transpose mat row col = {mat.[i + row*j] \\ i<-[0..col-1], j<-[0..row-1]}

class ` a :: !a -> a
instance ` MyRMatrix where
` a = {mat=transpose a.mat a.row a.col, row=a.col, col=a.row}

class (+@) infixl 6 a e:: (a e) e -> (a e)
class (@+) infixl 6 a e:: e (a e) -> (a e)
// ... その他略 matrix は RowMajor

193 :デフォルトの名無しさん:2005/10/30(日) 19:22:17
本当に最後に。
実用ならocamlのほうがよさそうだ。
本格派なら言語そのものの研究といった所かな?
ocamlは見た目が美しく感じないので好きじゃないんだけど。

素人の感想
Haskell :: スピードが遅く scheme で十分なので魅力を感じない
ocaml :: ライブラリが比較的充実?純粋関数型ではない
Clean :: マイナーでライブラリ作成が大変


194 :デフォルトの名無しさん:2005/10/30(日) 20:18:46
//おまけ 誤差逆伝播ニューラルネット。簡潔だが、知らないと結局わからない
// コンパイルも通してないし、行間を埋めなければならない代物
// local変数は構造体で作成みたいな感じがいいのかな。
learning :== 1.0
forwardPropagation i weights local
| i <= size weights = forwardPropagation (i + 1) weights
(copy local i (sigmoid local.[i] * weights.[i-1]))
= copy local i (sigmoid local.[i] * weights.[i-1])
backPropagation weights local pre i
#! weights = updateVector weights i (weights.[i] +learning@*(`local.[i])*pre)
| 0 == i = weights
= backPropagation weights local
( (1.0 @- local.[i]) .* local.[i] .* (pre * weights.[i]))
teach weights input teach n :== teach` weights
teach` weights _ 0 = weights
teach` weights i
#! local = forwardPropagation weights (makeLocal input)
=teach (backPropagation weights local (bp1 local.[size weights]) (n-1)) (n -1)
where bp1 last = (teach - last) .* last .* (1.0 @- last)


195 :デフォルトの名無しさん:2005/11/03(木) 21:12:26
一意性誤解してた。便利になると思ったが不都合発見。

module test
import StdEnv
::TestData = {a::!Int, b::!Int}

test1:: TestData -> *TestData
test1 xx=:{a,b} #!xx2 = {xx & a=a+1}
// = {xx & b=a+b+1} // xx , xx2の違い、コンパイルが通る。aの値もわかりにくい
= {xx2& b=a+b+1}

test2 :: *TestData -> *TestData
test2 xx=:{a,b} = {a=100+a,b=100+b}

test3:: {#Real}
test3 = {1.0,2.0}

Start #! (xx, yy) = (test1 cc, test1 cc)
#! xx = test2 xx
= (test1 xx, yy , test1 yy, test3.[1])
where cc = {a=1,b=2}


196 :デフォルトの名無しさん:2005/11/05(土) 08:15:35
一度書いてしまうと、急にはやめられないのでした。

Clean のゲームライブラリとかも結構強力ですね。
ゲームというより、ゲーム的な操作性・表現力を持つ物と考えれば幅は広がります。
Charlie が二週間でできたとのことです。
パフォーマンスが問題なければ実用にも。

…自分だけが書いていることには問題がありますが。


197 :デフォルトの名無しさん:2005/11/16(水) 00:17:45
最近ようやくgenericがわかりました。
haskellにも Generic Haskell なんてのがあるんだな。


198 :デフォルトの名無しさん:2005/11/27(日) 20:34:15
Cleanについて加筆

・産業指向であるため、活発な開発が行なわれない。(投資額が少ない場合)
・GUI や TCP などの関数型の苦手な部分こそ自前で持つという
新しい物を産みだすための良い哲学を持っている。
取り敢えず動く(CleanIDE や sample プログラムが動いている)。
・実行速度は安定しない (OS・ほんのちょっとのコードの変化で変わる)
が2倍速いマシンを買えば他より速くなるので問題ない
・前も書いたけどライブラリはほとんど無い。というか
有用なライブラリが美しく書けないのかもしれない。
Haskellでは Tree 等の複合的な型クラス に対する型クラスが書けるがCleanでは書けない。
class x1 a :: a -> a
class x2 a b :: (a b) -> (a b)
が別クラスになる。
または instance x1 Class1ElementXYZ のようにインスタンスの数だけinstanceが必要だ。
・タイムプロファイラーとか簡単に使えて便利だ。

>>195 のコードについて
意味的には TestDataはコピーされ * TestDataになるっぽい。(ただしメモリ上ではコピーではない)
これと似たようなことを配列でやっても失敗する。(コーピーされる場面もあるようだ)

言語的には OCaml よりは Clean の方がいいと思うんだが。


199 :デフォルトの名無しさん:2005/11/28(月) 00:54:27
書き忘れ、 一意配列について
lp :: *x a -> *(a , *x) | dup, f, end x // dup 架空の 複製関数
lp x y
# (x , x2) = dup x
# end x2 = (y , x)
# lp x (f x2 y)
dup で 複製した領域は再利用されなかった。されれば実装上fが一つに決まり楽になる。

//連想配列書いてみる。lookupはdynamic使ったりMaybeを使わないから実装多い
assoc e [] = Nothing
assoc e [x=:(a,b):xs]
| a == e = Just x
= assoc e xs
(%|%) infixl 9 :: (Maybe a) a -> a
(%|%) Nothing y = y
(%|%) (Just x) _ = x
assocx x alist :==
(@) infix 9 :: [(!String,!a)] !String ->a
(@) alist x = snd (assoc x alist %|% (abort ("assoc not match " +++ x)))
(:-) infixl 9 :: a b -> (a,b)
(:-) a b = (a,b)

al1 = ["test":-"test2","test2":-"test3","test3":-"test4"]
al2 = ["key1" :- ("key2", al1),"key3" :- ("key4", al1)]
Start#(str2, alist) = al2@"key1"
= str2 +++ alist@"test"


200 :デフォルトの名無しさん:2005/11/30(水) 20:36:55
200000000000000

201 :デフォルトの名無しさん:2005/12/01(木) 23:16:38
>>199 訂正
// 連想配列 ではなく 連想リスト
(@) infixl 9 :: [(!String,!a)] !String ->a

// infixlでないと ["key1":-["key2":-"val1"]]@"key1"@"key2" ができない
x@"test"@"test2" って見ても何が何だかわからないけど。
:: X2 = {test2::String}
:: X = {test::{#X2}}
x = {test={test2="val1"}}

Start = x.test.test2
// test , test2 は symbol nameとして出力できない
// また、リストは無限を含むこともできる

>>200
200000000000000
と言わず一言どうぞ


202 :デフォルトの名無しさん:2005/12/01(木) 23:42:59
Ocamlを調べてみるとgenericなしで
型クラスもない。
普通のオブジェクト指向はあるみたい。

………使いたくなくなった。


203 :デフォルトの名無しさん:2005/12/02(金) 05:45:07
Cleanをあまりよく知らないので関数型言語一般の話寄りになってしまいますが、
COMだとかActiveXだとかの外部のコンテナを扱いたい際は
データの副作用は純粋関数型言語ではどういった扱いになるんでしょうか?


204 :デフォルトの名無しさん:2005/12/02(金) 21:20:09
>>203
ここは参考になるかな?
http://www.haskell.org/hdirect/


205 :デフォルトの名無しさん:2005/12/02(金) 23:16:49
cleanではwrapper関数とか作ったり、一意ポインタを使ったりする。htoclean周辺参考

あまり実用ではない。

206 :デフォルトの名無しさん:2005/12/09(金) 01:18:06
一部語弊あり
>>198
> Haskellでは Tree 等の複合的な型クラス に対する型クラスが書けるがCleanでは書けない。
> class x1 a :: a -> a
> class x2 a b :: (a b) -> (a b)
> が別クラスになる。
> または instance x1 Class1ElementXYZ のようにインスタンスの数だけinstanceが必要だ。

arrayCopyRange:: !*(a e) !*(a e) !Int !Int -> *(!*(a e) , !*(a e)) | Array a e
arrayCopyRange x=:{[i]=xi} y i j
| i > j = (x,y)
= arrayCopyRange x {y&[i]=xi} (i+1) j

ちょっと面倒だが一応?書ける
一意性伝播がよくわからない。(エラーメッセージが…)

** 面白そうなファイル **
StdOverloadedList special なんてのがある

207 :デフォルトの名無しさん:2005/12/15(木) 03:29:16
遊び。 Haskell で書くとどうなるでしょうか?

//省略
readFile :: !String *World -> *([String],*World)

(<&|>) infixr 6
(<&|>) p1 p2 :== \x w= (\(y,ww)=(p2 y,ww)) (p1 x w)

a2l a = [e \\ e <-: a]

// uMap 既にありそう
uMap :: (a *w-> *(b, *w)) [a] *w -> *([b], *w)
uMap f [] w = ( [],w)
uMap f [x:xs] w
# (v , w) = f x w
# (vs , w) = uMap f xs w
= ([v:vs], w)

Start :: *World -> [[String]]
Start w =fst (uMap (readFile <&|> (map downcase)) (tl (a2l getCommandLine)) w)



208 :デフォルトの名無しさん:2005/12/15(木) 03:31:03
抜け落ち部分

downcase :: !String -> String
downcase str = {toLower x\\x<-:str}


209 :デフォルトの名無しさん:2005/12/15(木) 09:35:19
>207
Cleanはよく知らない俺がHaskellで書いてみましたよ。

import System.Environment
main = getArgs >>= mapM_ (putStr . map downcase . readFile)



210 :デフォルトの名無しさん:2005/12/15(木) 09:38:57
あ、しまった。 Haskell にも別に downcase はなかった。
import Data.Char
した上で
map toLower
だった。

211 :デフォルトの名無しさん:2005/12/15(木) 09:42:13
あー mapM_ の引数もおかしいし。
(\ fname -> readFile fname >>= putStr . map toLower)
ですかね

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

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.02 2018/11/22 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)