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

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

■ このスレッドは過去ログ倉庫に格納されています
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の仕様により、行頭の半角スペースは表示されません。
 コードをインデントしたいときは、代わりに または全角スペースを使うことができます。
0466デフォルトの名無しさん2007/01/08(月) 17:19:06
>>465
GHCを使ってるなら、-prof -auto-all付きでコンパイルして、
できた実行ファイルを+RTS -p付きで実行すると、
<実行ファイル名>.profというファイルにプロファイル結果が出力される。
詳しくはGHCのユーザガイドを読んでくれ。
0467デフォルトの名無しさん2007/01/08(月) 17:26:45
>>465

例:
ghc --make hoge.hs -o hoge.exe -prof -auto-all
hoge +RTS -p
type hoge.prof


Gtk2Hsのサンプルで.profファイルのビュアーがあるみたいね。
http://sourceforge.net/project/screenshots.php?group_id=49207&ssid=5881
0468デフォルトの名無しさん2007/01/08(月) 22:34:49
>>466,467
thx。

ユーザガイドのまるまる1章がProfilingなのね。
ざっと眺めただけだけど、heap profilingなんかは使い込むと便利そうだ。

まずは書いてもらった基本操作から使ってみるよ。
0469デフォルトの名無しさん2007/01/10(水) 11:02:23
質問です。
Haskellでは空リストがリストの終わりを表すと聞きました。
では、map関数を使って空リストに関数を適用させることは出来ないのでしょうか?
0470デフォルトの名無しさん2007/01/10(水) 11:11:25
ふつうのHaskell読んでるけどさっぱりわからん。
実際に組みながら覚えるのが良いんだろうけど・・・

自分としては最終的にはモナディウスみたいなゲームを作ってみたいのですが
グラフィックを扱うプログラムって、初心者には敷居が高いんですかね?

初心者がHaskellを覚える為に組むとしたら、どんなものがオススメですか?
抽象的ですみませんが、皆さんがどんなプログラム組んで覚えたかでもよいので教えてください。
0471デフォルトの名無しさん2007/01/10(水) 11:23:59
>>469
空リストがリストの終わりを表すのではなくて、空がリストの終わりです。
プログラミング的には空リストをリストの終わりとして処理しています。
空に関数を適用できません。

>>470
グラフィックスを扱うのはIO周りの事がよく理解できていれば可能だと思います。
0472デフォルトの名無しさん2007/01/10(水) 11:25:50
残念ながら日本語で書かれたよい文献はありませんのが、英語で書かれた読みやすい論文ならいくつかあります。
0473デフォルトの名無しさん2007/01/10(水) 11:28:37
↑の方のレスにいくつか論文が上げられていますね。
0474デフォルトの名無しさん2007/01/10(水) 11:28:40
各種UNIXコマンドとかがおすすめ。
ゲームプログラミングには Haskell は向いてないと思う。


>469
それくらいやってみりゃいいだろ。なんでいちいち聞くの。
Prelude> map id []
[]
というかなんで出来ないと思うのかがわからん。
0475デフォルトの名無しさん2007/01/10(水) 11:32:07
>>471
>空に関数を適用できません。
これはひどい。
0476デフォルトの名無しさん2007/01/10(水) 11:33:32
>>475
だったら空リストじゃなくて空に関数適用するようなHaskellコード書いてミロや!!!!
0477デフォルトの名無しさん2007/01/10(水) 11:47:52
>>476
あんたの空と空リストの定義がおかしいだけ
空リストは空そのものとして定義される。これは仕様書にもある。
0478デフォルトの名無しさん2007/01/10(水) 12:53:52
>>471,474
回答有難うございます。
結局空のリストに関数適用はできるという理解でよいのでしょうか?
Prelude> map id []
[]
このidという関数はどういう定義なのでしょうか?
また、
Hugs> map id [[],[],[]]
[[],[],[]]
という事も出来たのですが、この場合map関数は
「空リストのリスト」の最後に空リストがもう一こ上のレベル?で有るから
「空のリストのリスト」は終わりと判断して再帰を終わらせるという理解で良いでしょうか?
0479デフォルトの名無しさん2007/01/10(水) 13:37:57
>>476
まぁいいから外にでて空を見上げてみろ、今日は良い天気だ、「のどか」って書いてないか?
0480デフォルトの名無しさん2007/01/10(水) 14:09:22
空(カラ)なのか空(そら)なのか空(=NULL)なのか?定義してくれ。Haskell的に
0481デフォルトの名無しさん2007/01/10(水) 14:34:16
「外にでてから」だけでは推論に足りないって事か。
「屋外にでて上を見上げて」なら推論可能?
0482デフォルトの名無しさん2007/01/10(水) 15:33:24
>>478
idとmapの定義は

id :: a -> a
id x = x

map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs

この定義に従って、
map id [[],[],[]]
=> map id ([] : [[],[]])
=> id [] : map id [[],[]]
=> [] : map id ([] : [[]])
=> [] : (id [] : map id [[]])
=> [] : ( [] : map id ([] : []) )
=> [] : ( [] : ( id [] : map id [] ) )
=> [] : ( [] : ( [] : [] ))
=> [] : ( [] : [[]] )
=> [] : [[], []]
=> [[], [], []]
のように計算される。
0483デフォルトの名無しさん2007/01/10(水) 16:34:21
>>477
そんな記述はどこにもない。
あるというならどの文献のどのページにあるのか言ってみろ。
0484デフォルトの名無しさん2007/01/10(水) 16:42:38
個人情報じゃないけど何かあったみたい。
0485デフォルトの名無しさん2007/01/10(水) 17:49:05
>>482
すみません、

Prelude> map succ [1,2,3]
[2,3,4]

を実行するとちゃんと実行できるんですけど、

Prelude> map succ [[],[],[]]

<interactive>:1:4:
No instance for (Enum [a])
arising from use of `succ' at <interactive>:1:4-7
Probable fix: add an instance declaration for (Enum [a])
In the first argument of `map', namely `succ'
In the definition of `it': it = map succ [[], [], []]

を実行するとあまりうれしくない結果が出てきます。
どうしてですか?[]は何型なのでしょう・・・
0486デフォルトの名無しさん2007/01/10(水) 17:51:37
[1,2,3]の最後に入っている(という主張の)[]はInt型ですか?
0487デフォルトの名無しさん2007/01/10(水) 17:55:36
>>431
> square n が n * n と等値。
ええ?!じゃあ、たとえば、

test :: Int -> Int
x * x = test x

ってコンパイル通るんですか?!
0488デフォルトの名無しさん2007/01/10(水) 19:57:43
>>485
>どうしてですか?[]は何型なのでしょう・・・

結局の所、map succ [[], [], []] = [succ [], succ [], succ []]だから、
そのエラーはsucc []を実行しようとして失敗したってこと。
なんで失敗するかと言えば、succの引数はEnumクラスのインスタンスじゃないとダメなのに
[] は [a]型でEnumクラスのインスタンスではないから。

HugsとかGHCiでは関数とか値の型は :t 〜 って入力すればわかる。
例えば map succ の型を知りたい時は、
Prelude> :t map succ
map succ :: Enum a => [a] -> [a]
0489デフォルトの名無しさん2007/01/10(水) 20:06:26
>>488

mapsucc :: [Int] -> [Int]
mapsucc lst = map succ lst

試しに、上のようなコードを書いてみました。

mapsucc [1,2,3]

を実行すると、

[2,3,4]

のように表示されました。
ここまでは良いのですが、

mapsucc [[],[],[]]

を実行すると、

<interactive>:1:9:
Couldn't match `Int' against `[a]'
Expected type: Int
Inferred type: [a]
In the list element: []
In the first argument of `mapsucc', namely `[[], [], []]'

と表示されました。
おかしいですよね、これって。
0490デフォルトの名無しさん2007/01/10(水) 20:08:47
[a]って何ですか?空リストは空じゃなかったんですか?!!!!
0491デフォルトの名無しさん2007/01/10(水) 20:11:37
mapsucc :: [Int] -> [Int] なんだから mapsucc [[], [], []] の [[], [], []]は[Int]型だと思って評価しようとするんだけど、
[[], [], []] :: [Int] であるためには [] :: Int でないといけない。
だけど[]は[a]であってIntではない。よって型の不一致(Couldn't match `Int' against `[a]')
0492デフォルトの名無しさん2007/01/10(水) 20:22:32
>>491
空の型は総称的定義されているべきだと思うんですけど。
上のコードでは
mapsucc :: [Int] -> [Int]
のように明示的に書いたので、Int型にインスタンシエイトされるべきですよね?
0493デフォルトの名無しさん2007/01/10(水) 20:35:27
>>492
> 明示的に書いたので、Int型にインスタンシエイトされるべきですよね?
その理屈でいくと、[] + 1 :: Intとか1 + [] :: Int って書いたら
なんか適当なInt型の値が得られなきゃいけないって事?
0494デフォルトの名無しさん2007/01/10(水) 20:40:39
>>493
1+[]なんて定義できないよね。そう思うよね?
だから、空は抽象的なものであって、Haskellの仕様では、空リストと空は別ものなのです。
0495デフォルトの名無しさん2007/01/10(水) 20:58:04
そもそも >>469 に"Haskellでは空リストがリストの終わりを表す"と言ったヤツが勘違いしていると思う。

おそらく
[1,2,3] = 1 : [2, 3] = 1 : ( 2 : [3] ) = 1 : ( 2 : ( 3 : [] ) )
と分解できるから[]が終端なんだと言ったんだろうけど、
これは単に空リスト[]の先頭に3, 2, 1を順に追加していったものがリスト[1,2,3]だってこと。
もしくは、(有限)リストから先頭を取り除く操作をしていった場合、空リスト[]に行き着いた時点でそれ以上先頭を取り除くことが出来なくなるってこと。
0496デフォルトの名無しさん2007/01/10(水) 21:22:15
一応終端記号的なものとして空リスト[]があるからリストの終わりを表すというのは間違いでもないか。

ただ、リストの要素として[]がリスト[1,2,3]の終わりに入っていると考えるのは間違い。
0497デフォルトの名無しさん2007/01/10(水) 21:31:43
ふと思ったんだけど、量子コンピュータができれば、リストだけじゃなくて、本当の集合を扱えるようになるのかな・・・
0498デフォルトの名無しさん2007/01/10(水) 22:44:01
非決定性TMも実現できるんじゃね?
0499デフォルトの名無しさん2007/01/10(水) 22:55:26
>>497
本当の集合って何?
05004692007/01/10(水) 22:57:09
皆さん、自分が変な質問したばっかりに申し訳ないです。
>>495
すいません。「Haskellでは空リストがリストの終わりを表す」とは書いてないです。
やさしいHaskellのp36に
「空リストは特別な値で、リストの末尾に現れます」とあります。
で、自分が「C言語の文字列でいうところのヌル文字みたいなものだ」と
勝手に解釈したんです。
で、
「map関数で何かのリストに適当な関数を適用するとき、
リストの終端を判定するとき空リストがあれば、
再帰を打ち切る」んだなと思ったんです。
もし曲解している点があれば、指摘してください。
0501デフォルトの名無しさん2007/01/10(水) 23:14:43
>>500
Haskellのリストは単方向リスト。
Cの文字列みたいに何らかのターミネータを持つ配列じゃない。

struct LIST{void*value;struct LIST*next;};
Cで言うと(struct LIST*)NULLが空リスト。
要するにHaskellはnextの値が空リストかどうかで終端を判断している。
君はvalueが特殊な値('\0')のときに終端になるのだと勘違いしている。

と、説明書いてみたけど、うーん自分でもこれじゃあ分かりくいな。どうかけばいいだろう。
0502デフォルトの名無しさん2007/01/10(水) 23:34:08
Cで書くなら

enum Tag { NIL, CONS };
struct Nil { Tag t; };
struct Cons { Tag t; void *head; union List *tail; };
union List { struct Nil nil; struct Cons cons; };

という感じでないか
0503デフォルトの名無しさん2007/01/11(木) 03:18:20
Haskellのリストはモナドなので、Cで説明するのは骨が折れると思うから、モナドで説明した方が良いと思う。
0504デフォルトの名無しさん2007/01/11(木) 06:47:50
リストというのは、
Cons → 1

Cons → 2

Nil
というような構造になっていて、Haskellコードではこれを 1:(2:[])
と表現しています。 [] はこの場合の Nil のことを表す記号です。
いちいち 1:(2:(3:(4:[]))) と書くのは面倒なので
[1,2,3,4] と書いてもよくて、これは 1:(2:(3:(4:[]))) と解釈されます。
さて、map f という関数は、関数 f をこの Cons の右側につながった値に
それぞれ適用する関数です。
したがって、上の 1:(2:[]) に map f を適用した結果は
Cons → f 1

Cons → f 2

Nil
となります。
map f を [] に適用するとどうなるかというと、 [] は
 Nil
という構造なのでfを適用する値が一個もなく、したがって結果は
 Nil
のままです。よって map f [] の結果は [] となります。
0505デフォルトの名無しさん2007/01/11(木) 21:57:46
ふつうのHaskellと入門Haskell読み終わったくらいなんだけど、
SICPって読んだほうがいい?
0506デフォルトの名無しさん2007/01/11(木) 22:08:52
>>505
目的による。
何がしたいの?
0507デフォルトの名無しさん2007/01/11(木) 22:36:40
>506
最近寝付きが悪いので…
0508デフォルトの名無しさん2007/01/11(木) 22:39:11
>>507
読むことを激しく勧める
0509デフォルトの名無しさん2007/01/11(木) 22:47:17
サンクス。さっそく注文する。

この手の専門書は、原書より訳本の方がいいよね?
へんてこな翻訳文体が心地よい眠りに誘うと期待
0510デフォルトの名無しさん2007/01/11(木) 22:52:09
訳がむごいという人もいるが
よほどスラスラ英語を読めるのでもなければ
そんな訳でも訳の方がマシだと思う。
少なくともSICP程度の訳であれば。
0511デフォルトの名無しさん2007/01/11(木) 22:54:46
>>509
へんてこなのには違いないんだけど、なんか勝手に訳語作っちゃったり、痛さあふれる訳本です。
0512デフォルトの名無しさん2007/01/11(木) 23:11:24
訳語って翻訳者が勝手に作るものだと思ってた。
0513デフォルトの名無しさん2007/01/11(木) 23:20:11
>>512
偉い人が作って、みんながそれが正しいと思って使うようになるんだけど、
誰もその人の訳語を使わないし、そもそも新しい訳語を作れるほど自分は偉いんだ、
と思いこんでる身の程知らずのタコだから痛いんですよ。
0514デフォルトの名無しさん2007/01/12(金) 20:49:23
おまいら静かだけど、もしかして二チャンネル閉鎖騒ぎに参加してるですか?
0515デフォルトの名無しさん2007/01/12(金) 21:14:22
そんなくだらないことに参加はしないのです。
ただ議論がしたいからここを利用しているだけで、
なくなれば別のところにいくだけです。
0516デフォルトの名無しさん2007/01/12(金) 21:24:32
2chが閉鎖したときのためにHaskellについて議論できるような所ってどこがあるのかな
0517デフォルトの名無しさん2007/01/12(金) 21:35:57
http://www.sampou.org/cgi-bin/haskell.cgi?MailingList
で良いんじゃねぇ?
もしくはHaskellで適当な掲示板作るとか。
出来ないかな。
俺は2ch潰れて欲しいな。
人文科学の観点から、これほど大きい掲示板が潰れると
どういう影響が出るか見てみたい。
まるで夕張が国の実験場になるように。
0518デフォルトの名無しさん2007/01/12(金) 21:57:27
2chほど便利なコミュニティ+情報収集サイトは消えちゃマジで困る
個人的な立場で言うと、まじめにGoogle無くなるよりも困る
0519デフォルトの名無しさん2007/01/12(金) 22:11:42
俺としてはわりとどうでもいい。
ただ、専ブラの発明は偉大であると思ったので、
この方式自体は生き残るだろう。

ブログってRSSフィードを出力するのが増えてるけど、
専ブラで読める形式を出力するのってどうね?
とブログスレで提案したんだが、だれも作ろうとしない。

ああ、スレ違い
0520デフォルトの名無しさん2007/01/12(金) 22:27:13
専用ブラウザってのは2chのダメダメすぎる所を補うために出て来たもんであって、
無くて済むのならない方が良い。絶対に良い。
0521デフォルトの名無しさん2007/01/12(金) 22:36:48
そうかな
2chを毎日見る人間ってけっこう多いと思うぞ

インターネットと2chが1:1になるくらい
となるとブラウザと2chブラウザはわけて存在したほうがスッキリする
0522デフォルトの名無しさん2007/01/13(土) 03:20:14
ぐわぁ、どうも
文字
文字列
文字のリスト
文字列のリスト
の実感がイマイチわからねぇ。
関数の引数の型によって、文字のリストが文字列になったりその逆になったり
う〜ん。
あと、質問なんですけれども
多相型と型変数ってどこがちがうのでしょうか?
0523デフォルトの名無しさん2007/01/13(土) 03:32:11
>>521
オマエ、マチガエテル。
2ch ハ、インターネット ニ フクマレルカラ ソレジャ 2ch シカ リヨウシテイナイコトニナルネ。
2ch ブラウザ ガ アレバ ブラウザ イラナイネ。
0524デフォルトの名無しさん2007/01/13(土) 04:21:07
集約の関係なんてどうでもいいんだよハゲ
0525デフォルトの名無しさん2007/01/13(土) 04:57:05
>>522
C言語はchar配列が,いわゆる「文字列」じゃん
Haskellは [Char] が「文字列」

あと多相型を表現する(書き表す?)ために使われるのが型変数でそ
0526デフォルトの名無しさん2007/01/13(土) 05:23:40
じゃんじゃんでそでそ
0527デフォルトの名無しさん2007/01/13(土) 07:04:55
>>523
きっとインターネット以外のネットワークを使って2chにアクセスしてるんだよ。
0528デフォルトの名無しさん2007/01/13(土) 10:21:05
navi2chが使えて人がいればよくね?
0529デフォルトの名無しさん2007/01/13(土) 11:26:21
>>522
文字 Char
文字列 [Char]
文字のリスト [Char]
文字列のリスト [[Char]]
0530デフォルトの名無しさん2007/01/13(土) 11:27:01
type String = [Char]
0531デフォルトの名無しさん2007/01/13(土) 13:17:02
赤い彗星はシャア!
0532デフォルトの名無しさん2007/01/13(土) 14:05:00
     ll     ll
     l| -‐‐- |l
    ,イ」_  |ヽ_| l、
   /└-.二| ヽ,ゝl
   l   ,.-ー\/. 、l
  |  /.__';_..ン、    ビ〜ィ〜ム かがーやーく♪
  / /<二>  <二>!゙、
 //--─'( _●_)`ーミヘ    フラッシュバックに〜ぃ♪
<-''彡、   |∪|  、` ̄ ̄ヽ
 / __  ヽノ   Y ̄)  |
 (___)       Y_ノ
      \      |
       |  /\ \
       | /    )  )
       ∪    (  \
             \_)
         ll     ll
         l| -‐‐- |l
        ,イ」_  |ヽ_| l、
       /└-.二| ヽ,ゝl
       l   ,.-ー\/. 、l
      |  /.__';_..ン、  ヤツのかげーー♪
      / /<二>  <二>!゙、
     //--─'( _●_)`ーミヘ
    <-''彡、   |∪|  ミ __>
   (  (/     ヽノ_  |
    ヽ/     (___ノ
     |      /
   / /\  |
   (  (    ヽ |
  /  )    ∪
  (_/
0533デフォルトの名無しさん2007/01/13(土) 14:05:42

         _人人人人人人人人人人人人人人人_
           >  シャア♪  シャア♪  シャア♪  <
           ̄^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
     ll     ll          ll     ll          ll     ll
     l| -‐‐- |l  __     l| -‐‐- |l  __     l| -‐‐- |l  __
    ,イ」_  |ヽ_| l、〈〈〈〈 ヽ  ,イ」_  |ヽ_| l、〈〈〈〈 ヽ  ,イ」_  |ヽ_| l、〈〈〈〈 ヽ
   /└-.二| ヽ,ゝl.〈⊃  } /└-.二| ヽ,ゝl.〈⊃  }./└-.二| ヽ,ゝl.〈⊃  }
   l   ,.-ー\/. 、l |   |. l   ,.-ー\/. 、l |   | l   ,.-ー\/. 、l |   |
  |  /.__';_..ン、!   ! |  /.__';_..ン、!   !|  /.__';_..ン、!   !
  / /<二>  <二>!゙、 // /<二>  <二>!゙、 // /<二>  <二>!゙、 /
 //--─'( _●_)`ーミ /.//--─'( _●_)`ーミ / //--─'( _●_)`ーミ /
<-''彡、   |∪|  / <-''彡、   |∪|  /  <-''彡、   |∪|  /
 / __  ヽノ /     / __  ヽノ /    / __  ヽノ /
 (___)   /     (___)   /     (___)   /
0534デフォルトの名無しさん2007/01/15(月) 22:00:10
ここが噂の関数型言語スレか
0535デフォルトの名無しさん2007/01/15(月) 22:04:01
>>534
関数型言語の総合スレはこちらです↓

関数型言語Part IV
http://pc10.2ch.net/test/read.cgi/tech/1083649982/
0536デフォルトの名無しさん2007/01/19(金) 01:52:30

廃れてんなぁ
なんかHaskelニュースとかねーのか
0537デフォルトの名無しさん2007/01/19(金) 09:31:31
http://sequence.complete.org/hwn
0538デフォルトの名無しさん2007/01/20(土) 19:04:51
語ろう是!
0539デフォルトの名無しさん2007/01/20(土) 21:06:22
任せ炉!
0540デフォルトの名無しさん2007/01/21(日) 08:45:34
じゃあ質問。
やさしいHaskellのp107から。
myIf :: Bool -> a -> a -> a
myIf True t e = t
myIf False t e = e
main = do myif (True) (putStrLn "then") (putStrLn "else")
という関数を定義して、このプログラムがthenだけ表示されれば、
アクションputStrLn "elseは評価されていないことが分かります。
とあるんだけれど、何が言いたいのか良く分からん。
このプログラムを実行したら、thenが表示されるのは当たり前じゃないのか?
これのどこが評価に必要な式だけが評価されることの証拠になるんだ?
Cの
if ( True == True){
printf("then\n");
}
printf("else\n");
とどこが違うんだ。
これも、printf("else\n");は評価されて無いぞ。
それともif文を実装した点に意味があるって事?
0541デフォルトの名無しさん2007/01/21(日) 08:53:33
>>540
int myif(int a, int b, int c) {
 return a ? b : c;
}
int main() {
 myif(1, printf("true"), printf("false"));
}
0542デフォルトの名無しさん2007/01/21(日) 09:38:09
>>541
うん、それもわかるよ。
でもそれだって結局ifの言い換えでしょう?
俺が聞きたいのは
main = do myif (True) (putStrLn "then") (putStrLn "else")
でthenが実行されるのは当然で、何がすごいのか分からないんだ。
これと遅延評価の何が関係有るの?
教えて、偉い人。
0543デフォルトの名無しさん2007/01/21(日) 10:02:42
>>540
Cには「中身が実行されないことがある構文」(ifとか)はあるけど、
「引数が評価されないことがある関数」はない。
例えば、Cでは、
f(4 / 0)
という式は、fがどんな関数であっても零除算でエラーだが、Haskellでは、
f (4 `div` 0)
がエラーになるかどうかはfに依存する。
同様に、三項演算子と同じはたらきをする「関数」はCでは実装できないが、Haskellではできる。

>main = do myif (True) (putStrLn "then") (putStrLn "else")
ややこしいことに、この例に限っていえば、遅延評価は関係ない。
たとえputStrLn "else"が評価されたとしても、それで「else」が出力される訳ではない。
これはHaskellのIOの話で、遅延評価とは別の問題。
だから、遅延評価の話をするときは、ややこしくなるのでIOの例を使わない方が良いと思う。
0544デフォルトの名無しさん2007/01/21(日) 11:09:27
理解もできず、実際にコードのコンパイル・実行をしない奴に説明しても。
0545デフォルトの名無しさん2007/01/21(日) 15:55:04
GHC速報
http://tv.goo.ne.jp/contents/program/008/0004/20070122_0250/index.html
0546デフォルトの名無しさん2007/01/21(日) 17:08:29
>>545
ゴルァ!
0547デフォルトの名無しさん2007/01/22(月) 00:20:55
[ n | (n,True) <- zip [1,2,3,4,5] [True,False,True,False,False] ]
他のletの中とかならマッチしない時点でエラーが出ると思うのですが
なぜこのやりかたで絞込みができるのでしょうか?
内包表記が特別扱いされてるとか?
0548デフォルトの名無しさん2007/01/22(月) 00:31:11
>>547
リストはMonadPlusで、内包表記はdo記法の略記。
doの中でマッチングが失敗するとモナドのfailが呼ばれ、リストのfailはmzeroを返すから
その後に続く式が無効化される。
05495482007/01/22(月) 02:06:48
>>548
Prelude> let hoge = zip [1,2,3,4,5] [True,False,True,True,False]
Prelude> do (n,True) <- hoge; return n
[1,3,4]
Prelude> hoge >>= \(n,True) -> return n
[1*** Exception: <interactive>:1:49-69: Non-exhaustive patterns in lambda
なるほど。特別扱いではあるけどユーザも使えるわけですね。
0550デフォルトの名無しさん2007/01/22(月) 19:51:17
do記法ってsyntax sugerじゃなかったのね
0551デフォルトの名無しさん2007/01/22(月) 20:06:18
do P <- E ; REST...

E >>= \x -> case x of
  P -> do REST...
  _ -> fail "message"
の構文糖
0552デフォルトの名無しさん2007/01/22(月) 23:45:48
>>551
> doの中でマッチングが失敗するとモナドのfailが呼ばれ
というところが構文糖だけじゃないんじゃない?ということだと思う。
0553デフォルトの名無しさん2007/01/22(月) 23:47:25
すまん、書いてから551をじっくり読んだ orz
0554デフォルトの名無しさん2007/01/23(火) 02:07:43
Haskell98はdo経由せずにそのまま変換するようになってるな
[ e | p <- l, Q ] =
  let ok p = [ e | Q ]
      ok _ = []
  in concatMap ok l
[ n | (n,True) <- zip [1,2,3,4,5] [True,False,True,False,False] ]
  => let ok (n,True) = [n]; ok _ = [] in concatMap ok (zip [1,2,3,4,5] [True,False,True,False,False])
意味はほぼ一緒だが
0555デフォルトの名無しさん2007/01/23(火) 02:27:29
>>554
Haskell98ではなくて、GHCではそうだね。
0556デフォルトの名無しさん2007/01/23(火) 15:17:18
update :: Assoc a b -> a -> b -> Assoc a b
update h x v y | x == y = v
| otherwise = lookup h y
という関数の定義に関して、
update :: Assoc a b -> a -> b -> Assoc a b
の第一パラメータとなっている、Assoc a b は、
update h x v y | x == y = v
| otherwise = lookup h y
という実装において、
Assoc a b の a が h に、 b が x に対応しているのでしょうか?

よろしくお願いします。
0557デフォルトの名無しさん2007/01/23(火) 16:08:51
>>556
type Assoc a b = a -> b
と定義してあると思うので、それを前提にする。

>Assoc a b の a が h に、 b が x に対応しているのでしょうか?
違う。仮引数の型は、
h :: Assoc a b
x :: a
v :: b
y :: a

これは、updateの型をAssocなしで書いてみると分かり易い。
update :: (a -> b) -> a -> b -> a -> b
        h     x   v   y
0558デフォルトの名無しさん2007/01/23(火) 19:05:54
>>557
返信ありがとうございます。

>これは、updateの型をAssocなしで書いてみると分かり易い。
>update :: (a -> b) -> a -> b -> a -> b
>        h     x   v   y

とのことですが、

update :: Assoc a b -> a -> b -> Assoc a b
という定義には、その
>update :: (a -> b) -> a -> b -> a -> b
>      h    x   v   y
                 ↑
にあるような、y に相当するパラメータの指定が、
関数定義に存在していないのが理解できません。

これは何か特殊な仕掛けがあるのでしょうか?
0559デフォルトの名無しさん2007/01/23(火) 19:07:50
>>558
ずれてる。>>557をもう一度見返して。
0560デフォルトの名無しさん2007/01/23(火) 19:35:24
>>558
もっと単純な例を挙げる。

foo :: Int -> String -> Bool

という関数があるとする。これはもちろん二引数関数。
括弧を補って丁寧に書くと、この型は次のようになる。(納得できないならカリー化を復習すべし)

foo :: Int -> (String -> Bool)

ここで(String -> Bool)の部分を別名に置き換えても意味は変わらない。

type StringProp = String -> Bool
foo :: Int -> StringProp

こう書くとfooはいかにも一引数関数だけど、型は最初のfooと変わらない。
よって、実装を書く際は引数を二つ使える。例えば、

foo :: Int -> StringProp
foo n s = length s < n

ついでだが、
>関数定義に存在していないのが理解できません。
「update :: Assoc a b -> a -> b -> Assoc a b」みたいなのは型シグネチャといって、
ふつう定義とはいわないと思う。
0561デフォルトの名無しさん2007/01/23(火) 19:54:15
Haskellの標準GUIライブラリはどこにありますか?
0562デフォルトの名無しさん2007/01/23(火) 20:58:58
どこにも。
0563デフォルトの名無しさん2007/01/23(火) 21:09:00
どこにでも。
0564デフォルトの名無しさん2007/01/23(火) 22:01:08
>>559
>>560
返信ありがとうございます。

理解するに至りました。
どうもありがとうございます。
0565デフォルトの名無しさん2007/01/24(水) 01:49:28
圏論コミュがありえない展開
■ このスレッドは過去ログ倉庫に格納されています