トップページtech
1001コメント379KB

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

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん2006/11/07(火) 21:24:26
haskell.org
http://www.haskell.org/

日本語サイト
http://www.sampou.org/cgi-bin/haskell.cgi
http://shidot.dyndns.org/hs/

過去ログ
関数型プログラミング言語Haskell
Part1 http://pc.2ch.net/tech/kako/996/996131288.html
Part2 http://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 http://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 http://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 http://pc8.2ch.net/test/read.cgi/tech/1149263630/

関連スレは>>2
関連書籍は>>3

・2chの仕様により、行頭の半角スペースは表示されません。
 コードをインデントしたいときは、代わりに または全角スペースを使うことができます。
0877デフォルトの名無しさん2007/03/07(水) 00:13:36
>>876
手続き型言語で培った慣れが役に立ちにくいというだけであって、
学習の難しさはさほど変わらないんじゃなかろうか。
初めてプログラミングを習った人は大抵、
「思い立っても全く書けない」状態を経験するだろう。
0878デフォルトの名無しさん2007/03/07(水) 10:43:06
Haskellに限ればリスト覚えたら大体何とかなる希ガス
0879デフォルトの名無しさん2007/03/07(水) 20:46:20
そんなおれになんか課題だしてくれないか
ふつうのHaskellプログラミングでMAP関数のとこまでは読んだ
08808392007/03/07(水) 21:28:52
lispちょっと勉強してきました
cのプリプロセッサを強引に前処理としてかませば
lispのマクロと同じことができるかも
0881デフォルトの名無しさん2007/03/07(水) 21:36:55
どういう勉強をどれくらいしたのかは知らないけど、lispのマクロについてもっと勉強した方がいいよ。
0882デフォルトの名無しさん2007/03/07(水) 21:37:05
>>879
テキストファイルの各行を30文字に切り詰めるプログラム。
0883デフォルトの名無しさん2007/03/07(水) 21:39:07
>>880
Cプリプロセッサは実質的にチューリング完全だから能力は十分だけど、
Haskellの方がメタなことをするのに適していないような気がする。
例えば、局所的に型を宣言することができないとか。
0884デフォルトの名無しさん2007/03/07(水) 22:49:05
880じゃないけど
>Cプリプロセッサは実質的にチューリング完全だから能力は十分
これってホント?ループがかけないような
0885デフォルトの名無しさん2007/03/07(水) 22:49:53
局所的に型を宣言?ってどゆこと?
0886デフォルトの名無しさん2007/03/07(水) 22:50:39
自己includeでループはできそう。
0887デフォルトの名無しさん2007/03/07(水) 23:20:39
なるほど、define,ifdefとか組み合わせたらいけそうだな、納得
0888デフォルトの名無しさん2007/03/07(水) 23:46:56
881です。CPPがチューリング完全だとは知らなかった。その点は謝りたいと思います。


ところで、どうもまだ混乱しているんですが、自己includeのループをどう止
めたものかがわりません。 ifdef とかで何とかなるもんなの? define の再
定義では上手く行かないと思うんだけど。

たとえば階乗を計算するコードって、どんな概形になりますか?
# スレ違いすぎ?
0889デフォルトの名無しさん2007/03/07(水) 23:48:14
BOOST_PP
でループはできる
08908392007/03/07(水) 23:55:48
>>881
http://practical-scheme.net/wiliki/wiliki.cgi?Scheme%3aScheme%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9e%e3%81%ae%e3%83%ac%e3%83%99%e3%83%ab10
まだレベル1から2ぐらいです

これ以上勉強したらhaskellには戻ってこないと思う
0891デフォルトの名無しさん2007/03/08(木) 00:11:56
>>888
適当だけどこんなん用意して
#include<boost/preprocessor/slot/slot.hpp>
#ifdef N
    #define BOOST_PP_VALUE N
    #include BOOST_PP_ASSIGN_SLOT(1)
    #define BOOST_PP_VALUE 1
    #include BOOST_PP_ASSIGN_SLOT(2)
    #undef N
#endif
#if BOOST_PP_SLOT(1) == 0
    #define X BOOST_PP_SLOT(2)
#else
    #define BOOST_PP_VALUE BOOST_PP_SLOT(2)*BOOST_PP_SLOT(1)
    #include BOOST_PP_ASSIGN_SLOT(2)
    #define BOOST_PP_VALUE BOOST_PP_SLOT(1)-1
    #include BOOST_PP_ASSIGN_SLOT(1)
    #include __FILE__
#endif
こんな風に呼び出す。
#define N 6
#include "fact.c"
main(){
    printf("%d\n",X);
}
あとはC++関係のスレで
0892デフォルトの名無しさん2007/03/08(木) 00:42:45
>>888
俺が念頭に置いてたのはこんな感じ。
http://lists.boost.org/Archives/boost/att-46646/lambda.cpp

>>885
let data Foo = ... in ...
のように式の中で即席の型を作れると、C++のテンプレートの
真似ができるかと思ったが、良く考えるとそうでもなかったかも。
0893879じゃない2007/03/08(木) 01:49:32
>>882 できました!
でも、IOモナドはいまいちピンと来てないです。
あと、全部メモリに読み込んでから処理するのはいいんでしょうか(関数型だとそれがキレイ?)

import System.IO
import System.Environment
main = do args <- getArgs
      hFile <- openFile (head args) ReadMode
      content <- hGetContents hFile
      putStr $ unlines $ map (take 30) $ lines content


最後の行を
      mapM (putStrLn . (take 30)) $ lines content
にしてもいけました。

ツッコミお願いします
0894デフォルトの名無しさん2007/03/08(木) 02:03:52
>>893
お疲れさん。
>あと、全部メモリに読み込んでから処理するのはいいんでしょうか(関数型だとそれがキレイ?)
hGetContentsは全部メモリに読んでる訳じゃなく、入力は遅延する。
これはこれで気持ち悪い(副作用と紙一重)けど、便利なことは間違いない。
0895デフォルトの名無しさん2007/03/08(木) 02:18:49
単に読み込み専用で開けて読み込むだけならreadFileで良いと思う。

import System
main=getArgs>>=readFile.head>>=mapM_ putStrLn.take 30.lines
08968932007/03/08(木) 02:25:45
>>894
ありがとうございます!
Stringの値が必要になったら全読みされちゃわないんですか?
Stringのケツが必要になるまでは遅延される?

>>895
1行キタ─(゚∀゚)─!!!! まさに関数型!!!
関数合成ってそう使うんですね。初めてしっくり来ました。
08978932007/03/08(木) 02:55:18
おっとトラップ?
main=getArgs>>=readFile.head>>=(\c->mapM_ (putStrLn.take 30)$lines c)
にしないと、>>882の動きになりませんでした。
このラムダは消せないのでしょうか…?
0898デフォルトの名無しさん2007/03/08(木) 05:30:36
自分なら
main = getArgs>>=readFile.head>>=putStrLn.unlines.map (take 30).lines
とやる。
0899デフォルトの名無しさん2007/03/08(木) 06:30:58
>>897
main = getArgs >>= readFile . head >>= mapM_ (putStrLn . take 30) . lines

ちょっと分かりづらいか・・・。
0900デフォルトの名無しさん2007/03/08(木) 09:28:14
#includeで実現できるのはスタックにすぎない
よって実現できるのはプッシュダウンオートマトンであってTuring機械ではない
(外部スクリプトで複数回CPPをかけていいんならTuring完全になる)

ただしC++ templeteを使っていいならTuring完全になる
09018392007/03/08(木) 09:37:55
lispと比べたhaskellのメリットは

http://practical-scheme.net/wiliki/wiliki.cgi?Lisp%3A%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E8%AA%A4%E8%A7%A3&l=en
>なので、C並に速いLispコードは見た目も安全性もC並になる、というのが私 (Shiro) の経験です。

haskellの場合はC並にごちゃごちゃしなくてもC並の速度が実現できるということなのでしょうか?
0902デフォルトの名無しさん2007/03/08(木) 09:56:04
言語同士にはそんな単純に言い切れるほどはっきりとした差がつくもんじゃないよ
おもちゃベンチマークでもなければね

どうして安易な1フレーズの結論に飛びつきたがるのかなぁ
0903デフォルトの名無しさん2007/03/08(木) 10:22:58
>891
Boost だけど template を使ってるわけじゃないんだね。
漠然と、シンボルを結合したりしているのかな、とは思っていたが、うまい方法が思いつかなかったよ。ありがとう。
0904デフォルトの名無しさん2007/03/08(木) 10:38:50
>>900
>>892のリンク先のコード(β簡約器)はincludeを使っていない。
見れば分かるけど、λ式を最大nステップ簡約するマクロはO(log n)個のdefineで書ける。
だから「実質的に」チューリング完全、と書いた。

http://pc11.2ch.net/test/read.cgi/tech/1068359871/
完全にすれ違いなのでレスがあればこっちによろしく。(適当なスレが見付からなかったので)
0905デフォルトの名無しさん2007/03/08(木) 10:55:04
Boost PPの話はここに詳しい人がいると思います

Boostを語れゴラァ part3
http://pc11.2ch.net/test/read.cgi/tech/1158991211/
0906デフォルトの名無しさん2007/03/08(木) 12:15:39
>>899
最後は、mapM_の部分適用…と思って、小一時間悩みました。
最後は、(mapM_ (putStrLn . take 30)) . lines と評価されるんですね。

結合順位重要。関数適用最強…と。 _〆(。。)
0907デフォルトの名無しさん2007/03/08(木) 16:12:46
GHC使いなら -ddump-parsed をつけてコンパイルしてみるのも手かと。
0908デフォルトの名無しさん2007/03/08(木) 23:48:49
ちょっとやってみたけど


まぁまぁ面白いな
0909デフォルトの名無しさん2007/03/09(金) 03:49:25
>>907
知らなかった…。初心者にはあり難い。
0910デフォルトの名無しさん2007/03/09(金) 12:39:44
main = readLn >>= print . (1+)
を -ddump-parsed つけてコンパイルしてみたら(GHC6.6)

==================== Parser ====================
main = (readLn >>= print) . ((1 +))

って表示されたんだが、このパースは間違ってる。
実際、これをコンパイルすると型のミスマッチのエラーが起きるし。

本来は
main = readLn >>= (print . (1 +))
とパースされるわけで、実際処理系自体はそのようにパースしてるはず。
0911デフォルトの名無しさん2007/03/09(金) 13:05:50
結合の弱い順に演算子を使った
main = a >> b || c && d == e : f + g * h ^ i . j
に対しては
main = ((((((((a >> b) || c) && d) == e) : f) + g) * h) ^ i) . j
となった。どうも、演算子の結合強度を全く考慮していないらしい。
といっても、演算子の結合強度はパースしてみないと分からないので仕方ない。
0912デフォルトの名無しさん2007/03/09(金) 13:11:30
代わりに-ddump-rnを使えば良さそう。
09139072007/03/09(金) 17:16:48
>>912
あー、ほんとだ。こっちの方が正しいね。サンクス。
0914デフォルトの名無しさん2007/03/11(日) 12:39:27
main = writeFile "a.txt" "こんにちは"

GHC 6.6 Windows環境で上記ソースをUTF-8にして実行してみたんですが、
出力ファイル(a.txt)の中身が「S?kao」となってしまいます。
日本語を正しく出力するにはどうすればいいんでしょう?
0915デフォルトの名無しさん2007/03/11(日) 12:42:46
>>914
変換が要る。
>>402-414あたり参照。
0916デフォルトの名無しさん2007/03/11(日) 13:11:16
毛唐に任せてたら対応がいつになるか分かったもんじゃないぜ。
だれか直してパッチ送りつけろ。
0917デフォルトの名無しさん2007/03/11(日) 14:21:50
http://hackage.haskell.org/trac/summer-of-code/ticket/1113
これに応募するとか。
09189142007/03/11(日) 15:47:50
>>915
どもです。IOの標準ライブラリがUTF-8対応されたわけじゃないのですね。

日本語がどうしても必要な時はWinHugs使ってみます。
こちらはこちらでアンインストールできないバグがありますが・・・。
0919デフォルトの名無しさん2007/03/12(月) 00:09:24
これってWindowsAPIとか呼べますか?
0920デフォルトの名無しさん2007/03/12(月) 00:18:43
これってどれよ
0921デフォルトの名無しさん2007/03/12(月) 00:52:28
これっちゃこれよ
0922デフォルトの名無しさん2007/03/12(月) 01:27:08
importsのしたにSystem.WIn32.*ってあるな。
でもリファレンスには載ってない。System.Posix.*は載ってるのに。
0923デフォルトの名無しさん2007/03/12(月) 02:44:10
>>917
それは違うんじゃないか?
> * String/ByteString/UTF8String/UTF16String as filename
まあファイル名にも使えて然るべきだけど。
0924デフォルトの名無しさん2007/03/13(火) 16:39:59
>>923
コード変換が実装されない一番の原因は、今のGHCのIOライブラリが拡張しにくい
構造になっていることだから、それをまずなんとかするのが先決だ。
で、なんとかしようというのが>>917の提案だろう。
枠組さえできれば、コード変換を実装する事自体は難しくない。
0925デフォルトの名無しさん2007/03/13(火) 23:15:59

おまえらWindowsでHaskellしてんの?
Linuxの場合、Fedoraはいろいろ対応してるぽいが、
Debian系のUbuntuは使用不可能?
0926デフォルトの名無しさん2007/03/14(水) 02:00:13
>>924
いつのまにか書き換えられてるな。
・Various encodings (UTF8,UTF16...) for text files
もリンク先に増えてる。うしゃ。

しかし、
class Stringable a where
 length :: a -> Int
 concat :: [a] -> a
 ....

instance Stringable String
instance Stringable ByteString
instance Stringable UTF8String
instance Stringable UTF16String

なの?個々の文字はどうするんだ?
Charに32ビット使ってるのにUnicode(UCS4)のコードポイントそのまま使うんじゃないの?
つうか、リストじゃないの?そんなのありえるの?
0927デフォルトの名無しさん2007/03/14(水) 15:05:25
>>926
>個々の文字はどうするんだ?
http://darcs.haskell.org/SoC/fps-soc/Data/Stringable.hs
には、
class Stringable a where
  ...
  head :: a -> Char
  tail :: a -> a
  ...
というメソッドがある。

>Charに32ビット使ってるのにUnicode(UCS4)のコードポイントそのまま使うんじゃないの?
>つうか、リストじゃないの?そんなのありえるの?
何が言いたいか全然分からんw
もうちょっと詳しく。
0928デフォルトの名無しさん2007/03/14(水) 15:50:23
>>925
自分でコンパイルするとか
0929デフォルトの名無しさん2007/03/14(水) 19:59:59

Haskellの型推論って中の人どんなふうに動いてんの?

Javaにはそんな機能ないけど、
例えばプリミティブ型もIntegerとかにして、
ぜんぶをObject型で扱えば、なんでも突っ込めるようになるはずだけど、
それとはまったく違う?


0930デフォルトの名無しさん2007/03/14(水) 20:36:44
>>929
型推論と多相型をごっちゃにしてないか?
型推論は純粋にコンパイル時の操作で、一旦型が推論されたら、
明示的に型を書いた場合と全く同じようにコンパイルされる。
多相型の実装の話なら、その通りで、Javaのオブジェクトと同様あらゆる型をポインタを介して扱っている。
0931デフォルトの名無しさん2007/03/14(水) 20:44:47
Haskell の日本語の本2冊を一通りみたんだけど、
関数を返す関数が見当たらなかった?ような気がする。
Lisp 等だと普通に lambda を返す様な事をするけど、
0932ごめん。2007/03/14(水) 20:57:49
Haskell の日本語の本2冊を一通りみたんだけど、
カリー化された関数は作成してるけど、
無名関数を明示的に返す関数は無かったような気がする。
そんなのはあんまり書かないのかな?
0933デフォルトの名無しさん2007/03/14(水) 21:09:44
>>931
無名関数を明示的に返すくらいなら、最初からカリー化を利用して
引数を導入しておいた方が楽だからじゃないだろうか。
ただし、すでに名前の付いている関数を返すことはときどきある。
f :: Int -> Int -> Int -> Int
f 0 = (+)
f 1 = (-)
f 2 = (*)
とか。これの延長で無名関数を返すこともあるだろう。
f 3 = \x y -> if y == 0 then 0 else div x y
0934デフォルトの名無しさん2007/03/15(木) 00:52:08
>>927
勘違いしてたらスマンけど…。

Stringable aは、Stringable aであって[Char]じゃない
→リストじゃない→リストを扱う関数が使えないのでは?

UTF8Stringとかってエンコーディング処理が隠蔽されてるんだと思うけど、
今のStringの置き換えにするには、単純な[Char]に比べて性能遅そうな気が。

あと、エンコーディング毎に型が別ってのは、正しいのかも知れないけど、
コンパイル後に対応エンコーディングを増やすってどうやるの?

っていうか、ByteStringってエンコーディングは何?

と、疑問が山ほど。
0935デフォルトの名無しさん2007/03/15(木) 11:29:25
>>934
>Stringable aは、Stringable aであって[Char]じゃない
>→リストじゃない→リストを扱う関数が使えないのでは?
その通り。ただし
toString :: (Stringable a) => a -> String
fromString :: (Stringable a) => String -> a
は簡単に書ける。

>UTF8Stringとかってエンコーディング処理が隠蔽されてるんだと思うけど、
>今のStringの置き換えにするには、単純な[Char]に比べて性能遅そうな気が。
速度が多少犠牲になったとしても、空間効率が[Char]よりずっと良い。
[Char]だとGHCでは一文字あたり約20バイト必要だけど、UTF-8配列なら1〜4バイトで済む。

>あと、エンコーディング毎に型が別ってのは、正しいのかも知れないけど、
>コンパイル後に対応エンコーディングを増やすってどうやるの?
UTF*StringはあくまでStringの代替としての内部コードで、Stringの場合と同様に
入出力時にコード変換する使いかたが想定されているんだと思ったが、ちょっと自信がない。

>っていうか、ByteStringってエンコーディングは何?
本来のByteString(Data.ByteString.ByteString)はWord8の列なのでエンコーディングは関係ない。
ここで問題になってるのはたぶんData.ByteString.Char8.ByteStringで、これはLatin-1。
0936デフォルトの名無しさん2007/03/15(木) 12:13:27
>[Char]だとGHCでは一文字あたり約20バイト必要だけど、

まじですか。
Charのデータ自体は4バイトだから、
リストノードひとつに16バイトも必要なの?
でも、ポインタひとつ4(or8)バイト食えばそんなもん…か?

>UTF-8配列なら1〜4バイトで済む。
UTF-8なら1〜6バイトではないかと。まあ20バイトの比ではないが。
0937デフォルトの名無しさん2007/03/15(木) 12:28:16
Stringのcons
  enter : 4bytes -- クロージャ進入関数へのポインタ
  Char : 4bytes -- headへのポインタ
  String : 4bytes -- tailへのポインタ
Char
  enter : 4bytes
  Char# : 4bytes -- コードポイント値
計20bytes

確かめたわけじゃないけど、これで実測と合う。

>UTF-8なら1〜6バイトではないかと。
Unicodeの範囲(0..0x10ffff)なら4バイト以下で表せる。
0938デフォルトの名無しさん2007/03/15(木) 12:56:40
>>935
Stringable.hsにはtoString, fromStringじゃなくて、toList, fromListが定義されてるのでわざわざ書く必要すらない。
名前が違うだけで型は全く同じ。

>>934
対応エンコーディングを増やすためには適当なデータ型を用意してStringableクラスのインスタンスにしてやればよい。

おおざっぱにはこんな感じ。

data MyString = MyString ByteString

instance Stringable MyString where
empty = MyString empty
head (MyString bs) = (bsから先頭1文字分取り出してChar型の値にして返す処理)
...
0939デフォルトの名無しさん2007/03/15(木) 13:16:51
> toList, fromListが定義されてるのでわざわざ書く必要すらない。

それはわかるけど、リストで使うときとStringableで使うときで
バンバンそんな変換してたら遅いじゃん?
メモリ節約どころの騒ぎじゃないじゃん?

> 対応エンコーディングを増やすためには適当なデータ型を用意してStringableクラスのインスタンスに

そう言う事じゃなくて、プログラムとして、エンコーディングをpluggableに出来ないじゃんと。
例えば、Stringable を使って作られたエディタが配布されてるとする。
そのエディタに対して、対応エンコーディング追加プラグインみたいのが作れないのでは、という事。
あるいはプラグインでなくてもいい。
そのエディタ作者は英語しか出来ずStringableで書いても、入出力はLatin-1しか考えてない。
で、これを作者が存在すらしらない、SJISString, EUCJPString, Big5String みたいのを扱えるようにするには、
どうすればいいの?毎回ソース書き換えてリコンパイル?
0940デフォルトの名無しさん2007/03/15(木) 14:04:02
リスト的な操作をするときにいちいちリストに変換してやるわけじゃないんだけど。
mapとかfoldrとかいった操作は効率の良い定義に置き換えることも出来るようになってる。

pluggableに関しては、今のStringable.hsはそういう作りになってないんだから、書き換えてリコンパイルするしかないじゃん。
0941デフォルトの名無しさん2007/03/15(木) 14:11:15
>それはわかるけど、リストで使うときとStringableで使うときで
>バンバンそんな変換してたら遅いじゃん?
リストとして使いたいなら従来どおりStringを使えば良い。
そのためのinstance Stringable String。
0942デフォルトの名無しさん2007/03/15(木) 17:41:28
リスト一般用の便利なライブラリと、
Stringable用の便利なライブラリがあるとき、
変換せずに両方混在させて使える?

pluggableは、String以前に、Haskellでそもそも可能なの?
コンパイル時に知らないsubtype(クラスのインスタンス)を、
動的にファーストクラス値で指定してロードってできるんだっけ?
0943デフォルトの名無しさん2007/03/15(木) 17:49:20
>リスト一般用の便利なライブラリと、
>Stringable用の便利なライブラリがあるとき、
>変換せずに両方混在させて使える?
使える。Stringはリストであると同時にStringableなので。
0944デフォルトの名無しさん2007/03/15(木) 18:25:47
Haskellは実装の多重継承がokなんだな。
いわゆるダイヤモンド継承問題はどうなってるんだろう?
0945デフォルトの名無しさん2007/03/15(木) 18:49:02
Haskellに実装の継承に相当する機能なんてあったか?
0946デフォルトの名無しさん2007/03/15(木) 21:16:41
これが噂のオブ脳
0947デフォルトの名無しさん2007/03/15(木) 23:51:15
>>943
話の流れからして、StringじゃなくてUTF8Stringとかでそれが出来るかって話だと思うが。
0948デフォルトの名無しさん2007/03/16(金) 00:36:24
>>947
どこをどう読むとそういう話になるんだ?
ともあれ、UTF8Stringはリストじゃないので、リスト操作関数は使えない。
0949デフォルトの名無しさん2007/03/16(金) 02:05:56
>>937
クロージャ進入関数って?
データが関数のポインタを保持するの?
0950デフォルトの名無しさん2007/03/16(金) 02:08:59
結局の所 http://darcs.haskell.org/SoC/fps-soc/Data/Stringable.hs を読めってことになるんだが、
UTF8StringとかのStringableな型ではmap,take,foldrとかのリスト操作的な関数がデフォルト定義として与えられている。
だけどPreludeの同名の関数たちとは型が違うから、単にimport Data.Stringableとすると衝突してしまう。
なので、実際に使う時はimport qualified Data.Stringable as S みたいにして、
Stringable用の関数は S.map, S.take, S.foldr のようにS.を付けて使うことで衝突を回避する。
0951デフォルトの名無しさん2007/03/16(金) 02:40:48
>>949
Haskellではデータ構造の一部が未評価のことがあり得るので、
評価用の関数ポインタを保持せざるを得ない。

>>950
基本的な関数はStringableクラスにもあるけど、
リストにしか対応していないライブラリも多い(例えばParsecとか)。
「リスト操作関数」という言い方が悪かったか。
0952デフォルトの名無しさん2007/03/16(金) 03:03:53
Parsecが使えない文字列なんて…。
っていうか、Stringableとリストのクラスを作るんだよね?(:)とかheadとかtailとか++とか!!とか。
それでも現行のリスト用ライブラリは使えないけど、じきに対応してくれるのを待つ、と。
でも構文的な問題が厳しいか。
0953デフォルトの名無しさん2007/03/16(金) 03:29:21
>>952
>Parsecが使えない文字列なんて…。
何を問題視しているのかさっぱり分からん。
従来ファイル名にはStringしか使えなかったのを、Stringableのインスタンスならどれでも
使えるようにしよう、という互換性を保った拡張であって、Stringで満足しているなら
Stringを使いつづければ良いんだが。
0954デフォルトの名無しさん2007/03/16(金) 03:56:39
Haskell ぼろぼろじゃん
0955デフォルトの名無しさん2007/03/16(金) 09:22:14
コンストラクタになる関数とパターンマッチで使う逆関数を用意したら既存のdataが拡張できるような仕組みがあればいいのに
遅そうだけど
0956デフォルトの名無しさん2007/03/16(金) 09:32:26
extendedList :: (a -> b -> b) -> b -> (b -> Maybe (a, b)) -> (b -> [a], [a] -> b)
extendedList cons nil match = (forth, back)
  where
    forth = unfoldr match
    back = foldr cons nil
0957デフォルトの名無しさん2007/03/16(金) 18:18:58
>>953
          非Latain-1  リストベースライブラリでの使用
String       ×         ○
Stringable     ○         ×
望まれる物   ○         ○

例えば、(メモリ効率の改善はなくなるが)
バイト列とStringの変換関数だけを提供するという解も有り得るかと。

あるいは、Stringableの方向性でいくなら、
Stringableをリストの「インスタンス」にするか、それが無理なら
リストとStringableを包含したクラスを作って、リストの構文でも扱えるようにすれば、
リストベースライブラリもわずかな修正とリコンパイルだけでStringableでも使用できるようになるのでは?
0958デフォルトの名無しさん2007/03/16(金) 19:26:12
>>957
・Stringという型とStringableというクラスを比較するのはおかしくないか?
・Stringでも非Latin-1の文字は使える。

俺ならこういう表にする。

       Parsec(リストのみ) 現行IO(Stringのみ)  提案IO(Stringable)
String       ○           ○             ○
UTF8String    ×           ×             ○
[Word8]      ○           ×             ×

>>917のリンク先の提案は、「IO」という縦の列の改善提案であって、
例えばUTF8StringがParsecで使えるかどうかとは関係ない話だと思うが。
「リスト的なコンテナ」を表現する型クラスがあっても良いとは思うけど、
それは少なくとも>>917とは別の話題だと思う。
0959デフォルトの名無しさん2007/03/17(土) 03:53:19
とすると、>>917>>914-916とは別の話題だったということか。

それはともかく、
・Haskell(Hugs/GHC)自体は、FPSは関係なく、ちゃんと
 CharにUnicodeコードポイントを(1byteずつに分けずにまるごと)入れて、
 readFileとかputStrとかが適切にデコード・エンコードしてくれる方向
・FPSは、それとは直交して、
 効率の良いString(able)クラスを作ろうとしていて、
 エンコーディングも扱う
と理解してOK?

しかし、せっかく作るStringableだが、
Parsecなどのリストベースのライブラリで使えないというのは、勿体ないとは思わない?
リスト派とStringable派にライブラリが分裂しちゃうじゃん。無駄じゃん。

文字エンコーディング機能が、
readFileとかの関数と、Stringableのインスタンスの両方に実装されるのも
DRYじゃないし、テキストを扱う流儀の分裂を招く。
0960デフォルトの名無しさん2007/03/17(土) 10:09:28
ByteStringでもPersecを使えるようにしようって話もあるみたい。
http://hackage.haskell.org/trac/summer-of-code/ticket/59
0961デフォルトの名無しさん2007/03/17(土) 12:27:33
>>959
>とすると、>>917>>914-916とは別の話題だったということか。
いや、>>917はGHCのIOライブラリを作りなおそうという話であって、Stringableの提案は
その一部に過ぎない。ので全体としては関係あると思う。

>しかし、せっかく作るStringableだが、
>Parsecなどのリストベースのライブラリで使えないというのは、勿体ないとは思わない?
>リスト派とStringable派にライブラリが分裂しちゃうじゃん。無駄じゃん。
確かに。

>文字エンコーディング機能が、
>readFileとかの関数と、Stringableのインスタンスの両方に実装されるのも
>DRYじゃないし、テキストを扱う流儀の分裂を招く。
これは仕方ないような。readFileがやるのは
外部エンコーディング <-> 内部エンコーディング
の変換で、例えばUTF8Stringが行うのは内部エンコーディング間の変換。
0962デフォルトの名無しさん2007/03/17(土) 15:46:20
よくわからんけど
(:)とか[]は
Stringableじゃ使えないのか。
0963デフォルトの名無しさん2007/03/17(土) 16:09:48
例えばUTF8Stringな s に対して 'a':s みたいなことは出来ない。
0964デフォルトの名無しさん2007/03/17(土) 16:25:48
Stringableとリストを共通クラス化しておかないと、
リストを使った実装群と、Stringableを使った実装群に分断される。

将来絶対、混乱や重複実装の元になって問題になるだろ。どうにかしろよ。
0965デフォルトの名無しさん2007/03/17(土) 16:29:23
リスト系関数使えないってかなりまぬけだ
0966デフォルトの名無しさん2007/03/17(土) 16:37:47
はぁ?頭悪い人か
0967デフォルトの名無しさん2007/03/17(土) 16:42:27
>>946
 >>944=Tucker!
 C++が最高だと思って相手構わず噛み付く痛い人だから
 相手にしなくておk

 monadic programming の主旨も理解できてないレベル
0968デフォルトの名無しさん2007/03/17(土) 16:42:50
>>966
使えるのか?
同名の関数があるってオチは無しだぜ?
0969デフォルトの名無しさん2007/03/17(土) 17:30:30
> Stringableとリストを共通クラス化しておかないと、

一応リストっぽい操作を持つ型構築子クラスとしてはData.Foldableってのがある。GHC 6.6で追加された。
ただ、これを使ってUTF8StringをFoldableのインスタンスにすることはできない。
なぜならUTF8Stringは型であって型構築子ではないから。
一旦type UTF8String = UTF8StringC Charみたいなものを考えて
UTF8StringCをFoldableのインスタンスにすることは出来るだろうけど、それってどうなんだろう。
0970デフォルトの名無しさん2007/03/18(日) 03:55:42
型はそれで一応解決?としても、
 : と [] は言語仕様の方に手を入れるしか。
[]は単なる糖衣としても、 : は?
0971デフォルトの名無しさん2007/03/18(日) 09:58:34
>>969
それだと、UTF8StringC Doubleなんていう型を作れることになるな。
まじめにリストをクラス化するとしたらこうだろう。
class List container element | container -> element where
  nil :: container
  cons :: element -> container -> container
  match :: container -> Maybe (element, container)
  ...
で、
instance List [a] a
instance List UTF8String Char
...
しかし、これってやるに値することなのかな。
型クラスを介して操作するなら、コストの点ではリストに変換してしまうのと大差ないような。
0972デフォルトの名無しさん2007/03/18(日) 10:24:52
うん、そういう変なのが作れちゃうからどうなんだろうって思った。

> class List container element | container -> element where
関数従属って全然使ったことないから思いつかなかったな。
0973デフォルトの名無しさん2007/03/18(日) 11:47:29
これはとんだコードは簡潔だけど記述するのに30倍くらい時間のかかる糞言語ですね
0974デフォルトの名無しさん2007/03/18(日) 11:54:27
>>973
どういうコードを書いているかにもよるが、Haskellじゃなくて
お前が糞である可能性も十分にあると思う。
特に、コードが簡潔なのに書くのに時間がかかる場合、
不慣れなだけな可能性が高いかと。
0975デフォルトの名無しさん2007/03/18(日) 12:06:33
馬鹿を寄せ付けない言語として最強
馬鹿はJavaでもやってろwwwwww
0976デフォルトの名無しさん2007/03/18(日) 14:36:27
>>971
>型クラスを介して操作するなら、コストの点ではリストに変換してしまうのと大差ないような。

Stringableも型クラスじゃん。違うの?
どうせ型クラスなら、分断と混乱を防いだ方が良いと思うけど。
レス数が950を超えています。1000を超えると書き込みができなくなります。