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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2012/03/16(金) 21:54:23.92
haskell.org
ttp://www.haskell.org/

日本語サイト
ttp://www.sampou.org/cgi-bin/haskell.cgi
ttp://www.shido.info/hs/

過去ログ
関数型プログラミング言語Haskell
Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html
Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/
Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/
Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
Part17 ttp://toro.2ch.net/test/read.cgi/tech/1325510368/
0232デフォルトの名無しさん2012/04/29(日) 17:10:59.47
>>231
モナド則でこうなってるから
(m >>= f) >>= g == m >>= (\x -> f x >>= g)
0233デフォルトの名無しさん2012/04/29(日) 17:21:25.38
>>231
(>>=)は左結合だけどdoは右結合だから問題ない
明示的に(>>=)とラムダを使う場合でも、
a >>= \x ->
b >>= \y ->
c
なら、
a >>= (\x ->
b >>= (\y ->
c))
のことだから、やはり問題ない(ラムダ式は可能な限り右まで続く)

>>232
モナド則は関係ない
0234デフォルトの名無しさん2012/04/29(日) 18:17:44.38
>>233
……infixl 1と宣言しておきながら、事実上は右結合なんですか?

右結合って短絡可能なんですよね?

Maybeモナドでは
左にNothingなら問答無用でNothing
ってなってるけど

処理が右結合で、途中Nothingに出逢ったら
Real World Haskellではそのまま最後までNothing伝播処理が続くって書いてあった

でも僕の考える限りでは、右結合では右側が判明するまでの必要最低限の努力をするのが遅延評価だから
途中でNothingに出逢った瞬間からスタック巻き戻しのようになると思うのですが……


/\
 /\
  /\
  N /\
    /\
      :
      /\
       /\
/\
 /\
   N
/\
  N

Nothing
0235デフォルトの名無しさん2012/04/29(日) 19:24:55.15
>>234
構文の話と意味の話をごっちゃにしてないか
左結合(infixl)というのは、あくまで
a >>= b >>= c
というふうに使ったときに
(a >>= b) >>= c
と解釈される、というだけの意味。それ以外の使い方をした場合には関係ない

後半はその通りで、(Nothing>>=f)はfを呼ばないから、たとえばdoの中でNothing
が出て来たらそれ以降は評価すらしない
そのNothingが別のdo(呼び出し元の関数とか)に渡ったときには
Nothingの伝播処理が挟まる
0236デフォルトの名無しさん2012/04/29(日) 21:27:11.79
>>235
質問@
 Maybe 上で (>>=) あるいは (>>) を使ってたくさんの計算を連鎖するとき、
その計算のどれかが Nothing を返したら、残りの計算は一切評価されません。
 しかしこの連鎖は完全には短絡されていないことに注目しましょう。
連鎖中のそれぞれの (>>=) や (>>) は左の Nothing にマッチすると右に Nothing を生成し、
最後までそうしていきます。この点は忘れやすいものです。
連鎖中の計算が失敗したとき、それに続くNothing 値の生成、連鎖、消費は実行時に安価ではありますが、タダというわけではありません。


348 P にこう書いてありますが、私にはこの文脈が左結合を示唆しているかのように見受けられます。つまりは、
  /\
 /\
/\
N
 /\
/\
N

/\
N

Nothing
こう主張しているように思えるのです。短絡は起きていないように思えます。

ここで私のいう短絡とは、関数処理のスキップのみならず木構造の一発切除をも意味します
Nothingに出逢った瞬間全てを忘れて即Nothingです

これは無理なのでしょうか?
0237デフォルトの名無しさん2012/04/29(日) 21:31:47.75
>>235
質問A
余談ですが考えてもみれば、左結合は(関数処理は省けても)そのまま最後まで構造が進むしか無いようで、
一方で右結合は構造も短絡できるかのように見えますが、
構造の最後の方でNothingが発生するか、結局最後まで発生しなかった場合を想像すると、
スタック巻き戻しを考慮に入れると、行って戻ることになり、
最後まで構造をなぞるどころかその2倍弱の手間になるかも知れませんね。

より最初の方でNothingが出る期待が高い時は右結合
そうでない時は安定的な左結合が適切なんでしょうか?

Data.List.and と or は右結合で定義されていますが
これは何を意識してのことでしょうか?

and/orの最後の方でFalse/Trueがでるか、あるいは最後まで出ない時、
(これは直感ですが)リストの半分を越えてから結論出せる状況になったら、
正格左結合よりも酷いパフォーマンスになるのではないでしょうか?

スタックを巻き戻すだけというのが、パターンマッチングで値を返す処理に比べて、
凄く速いのならそんな事は無いといえるのでしょうが。
0238デフォルトの名無しさん2012/04/29(日) 22:32:05.06
木構造だとか関数処理とか怪しい概念は窓から放り投げて定義の展開と代入、簡約で考えよう
その辺はRWHよかIntroduction to Functional Programming using Haskellの方が詳しいyp

andやorが右結合なのは無限リスト食わせるとわかる
foldlで定義したら食わせるリストの頭に零因子であるものがあってもスタック食いつぶす

Maybeに関しての短絡はNothing >> forever (Just 1)とかするとわかる
これが木構造とやらを切除しないとなるとサイズが無限である木がメモリ上に存在してスタックオーバーフロー起こす事になる
0239デフォルトの名無しさん2012/04/29(日) 23:59:04.07
初心者に信用されてないんだなあHaskell
0240デフォルトの名無しさん2012/04/30(月) 03:31:17.36
手持ちの情報だけで突っ走ってしまう人がいるのはHaskellに限った話ではない
0241デフォルトの名無しさん2012/04/30(月) 09:20:17.79
>>239
「信用」の意味がよく分らないです

Haskell は初心者から、本来あるべきどのような信用がないのでしょうか
0242デフォルトの名無しさん2012/04/30(月) 09:55:23.07
>>214
くっそこんなので笑わされるとは
0243デフォルトの名無しさん2012/04/30(月) 10:03:34.53
鳩丸
0244デフォルトの名無しさん2012/04/30(月) 11:13:59.36
暗黙の型変換の仕組みは Haskell では作れないのでしょうか(GHC の拡張機能なとで)

例えばリテラルからの暗黙の型変換は一部ありますよね
Num.fromInteger 関数とか IsString.fromString 関数を定義しておけば、
リテラル整数や文字列を適切な型にコンパイラが自動的に変換してくれる
(後者は GHC の拡張機能ですが)

これの延長で、例えば OpenGL を使っていて、
GLdouble 型を引数に取る関数を Double 型に適用しようとした時、
何か特別な定義をしておけば、realToFrac 関数を使わずとも、
コンパイラが自動的に変換してくれるとか

このような例だけでなく、一般的に fromIntegral 関数とか realToFrac 関数って、
けっこう目障りなんですよね

これらって、型推論出来るようにコードを書かなければならないという、
どちらかと言うと言語仕様よりの概念じゃないですか
そのわりに、realToFrac 関数だけでは、ぱっと見、何から何への変換か分らない

一方で、これらの関数が使われているコードは、
何を計算するのかという、もっと抽象度の高い概念をコード化しているわけで

抽象度の高いコードの中に、抽象度の低い「おまじない」の様なコードが
けっこう大きな石ころのように混ざっている状況が、なんとも違和感を覚える

どうにかならないものでしょうか
0245デフォルトの名無しさん2012/04/30(月) 11:26:54.17
>>241
うーん、言語の設計者より自分の方が頭いいかもしんない、と思われちゃってるところ。
0246デフォルトの名無しさん2012/04/30(月) 11:45:17.37
どうでもいいレスに反応して戦線を拡大したがるあたり
抽象度とか言いつつ全体が見えていない
0247デフォルトの名無しさん2012/04/30(月) 11:57:23.83
>>238
有難うございました(´;ω;)
0248デフォルトの名無しさん2012/04/30(月) 14:53:15.43
GHCiで入力に関して、重複する履歴は考慮しないようにするにはどうしますか?
上を押しても同じ履歴だった場合、動いてないように見えてストレスとなります
0249デフォルトの名無しさん2012/04/30(月) 15:06:17.22
>>248
残念ながら現状ではどうにもならない

なにかストレスを発散する方法を考えてくれ
0250デフォルトの名無しさん2012/04/30(月) 15:30:36.77
サンクスエニウェイ
0251デフォルトの名無しさん2012/04/30(月) 18:34:46.96
haskelineを直してパッチ送ればいいんじゃね
0252デフォルトの名無しさん2012/04/30(月) 18:36:44.31
むしろこのスレの初心者の扱いの酷さに引いた
0253デフォルトの名無しさん2012/04/30(月) 18:38:36.11
定番の頭の悪い攻撃ですな
0254デフォルトの名無しさん2012/04/30(月) 23:24:32.16
初心者質問スレはまだ不要?
0255デフォルトの名無しさん2012/04/30(月) 23:33:00.05
今まで初心者らしい素朴な質問を見たことがない

・どうやってボタン表示するんですか
・ループが出来ません
・変数変えれないんですけど

そんな質問しねーよ、って人ならもう初心者じゃない

具体的に「Haskellでやりたいこと」を見つけて取り組んでくれ
分かんないことがあったらピンポイントで質問してこい
あたしらが優しく相手してやる
0256デフォルトの名無しさん2012/05/01(火) 00:09:38.80
HappyのGLR機能が保守放棄されている(現行のghcで動かない。バグもあるらしい)のですが、
今生きているHaskellのGLRパーサはありませんか?
0257デフォルトの名無しさん2012/05/01(火) 03:16:34.46
>>255
お、お前……女だったのか……。
0258デフォルトの名無しさん2012/05/01(火) 03:22:27.79
Haskellでメタプログラミングしたいんですけど,
具体的には今あるコード資産に対してコード変換して,機能拡張したい,
そのための便利な仕組みない
0259デフォルトの名無しさん2012/05/01(火) 04:32:54.50
>>252
いんや?
自分が初心者の頃、親切に教えてもらったぞ?

プログラミングHaskellで最初に詰まって、散々悩んだreplicateのリスト内包表記版を作れって問題とか

初心者でも、replicateの再起版はすぐに思いついたんだが、この頃は本当に頭が固かったな・・・
(ヒントがlengthのリスト内包表記版の応用って書かれてても、全然思い浮かばんかった)

回答してもらって、ああ、なるほど、lengthのリスト内包表記版の応用だ。ってやっと納得できたっけ

そもそもHaskellはRubyとかと違って、組込み関数も自分で簡単に作れるってのが初心者の頃の自分には言語の理解の助けになった
普段自分の使ってる関数の動きを自分で同じ関数作って確認しながら覚えられるから、あんまり基本的過ぎる質問ってする必要が無かったし、
>>255同様、初心者らしい質問って、そもそもHaskell(または関数型言語)ってどんな言語?とか以外じゃ見ない(それも最初のスレだけだったような・・・)
当時の自分の質問が一番初心者らしい質問だったと思う
0260デフォルトの名無しさん2012/05/01(火) 06:00:09.93
[(x,y) | x <- [1..], y <- [1..], 3^x - 2^y == 1]

深さ優先探索なので,(1,1)の後は事実上フリーズします

これを深さも幅も均衡して広げて探索していくにはどうしますか?
0261デフォルトの名無しさん2012/05/01(火) 06:38:12.34
>>260
[(x,y) | x <- [1..], y <- [1..x], 3^x - 2^y == 1 ||  3^y - 2^x == 1]
0262デフォルトの名無しさん2012/05/01(火) 08:47:38.24
>>259
昔のことは知ってるよ。Part3くらいから居る
>>231を馬鹿にする流れを見て、正気か?と思っただけ
0263デフォルトの名無しさん2012/05/01(火) 09:44:02.40
馬鹿にしてるってどの辺が?
0264デフォルトの名無しさん2012/05/01(火) 15:45:08.13
>>261
面白いハックです
ありがとうございました
0265デフォルトの名無しさん2012/05/02(水) 16:26:57.40
無限モナドリストを受けて
条件を満たす最初の要素を束縛するにはどうしますか?
0266デフォルトの名無しさん2012/05/02(水) 17:20:16.04
モナドリストって何?
[a] ?
Monad m => m [a] ?
Monad m => [m a] ?

基本はData.List.find (:: (a -> Bool) -> [a] -> Maybe a)と同じで、型に合わせてliftMしたりすればいいと思うよ。
ただ無限リストなので、条件を満たす要素がなかったら計算が終わらない。
これはしょうがない。
0267デフォルトの名無しさん2012/05/02(水) 21:56:17.29
>>266
後者です

findでやってみようと思ったんですが
術語が Int -> IO Bool なんです

filterM みたいに findM があればいいと思いますが

filterMしてheadって不格好です
きっとスマートな解決法がある筈です
0268デフォルトの名無しさん2012/05/02(水) 22:03:05.12
ああそれからモナドの性質上
無限のモナドのリストを渡すとフリーズしますよね

最初、遅延評価なのになんで正格評価みたいになってんだと首を傾げたのですが
考えてもみれば、順序を保証するんだからfilterMに無限のモナドのリストを渡すと
そのリストの最後の評価が済むまで次の行けないですよね
困りました
0269デフォルトの名無しさん2012/05/02(水) 22:20:28.35
>=> 地味に便利ワロタ
0270デフォルトの名無しさん2012/05/02(水) 22:54:51.28
[IO a] じゃなくて IO [a] で [a] が無限リストなら
どうもならん、諦めろ
0271デフォルトの名無しさん2012/05/02(水) 23:45:26.55
[IO a]で無限です
0272デフォルトの名無しさん2012/05/03(木) 00:06:04.51
Data.Listでの実装は
find p = listToMaybe . filter p
だぞ。別に filterM して head も似たようなもんじゃないか?

[IO a]でもIO [a]でも無限リストで要素が無ければ止まらないのは
一緒だと思う。
0273デフォルトの名無しさん2012/05/03(木) 00:27:44.81
>>272
はい(´・ω・`)
0274デフォルトの名無しさん2012/05/03(木) 00:29:59.11
filterM して head ってのはこれ?
これは要素があっても[IO a]が無限リストなら停止しないよ

findM' :: Monad m => (c -> m Bool) -> [m c] -> m c
findM' f = head <=< filterM (join . liftM f)


一方、こっちは要素があれば止まる(無ければ止まらない)

findM :: Monad m => (a -> m Bool) -> [m a] -> m (Maybe a)
findM f [] = return Nothing
findM f (x:xs) = do
  v <- x
  t <- f v
  if t then return $ Just v else findM f xs


テストしてみれば分かる

ms :: [IO Int]
ms = map return [1..]

main = do
  --print =<< findM' (return . (> 10)) ms
  print =<< findM (return . (> 10)) ms
0275デフォルトの名無しさん2012/05/03(木) 05:20:09.91
ほんとですね
無限リストでfilterMは危険なのか。
0276デフォルトの名無しさん2012/05/03(木) 06:33:35.38
>>274
ありがとうございました

filterMに倣って
findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
版を作って使ってみましたが、何だかソースが汚れた気がします

Maybeを取扱う為に一々letやcaseを挿入しないとならなくなったせいでしょうね

しょうがないでしょうが

ところで何故標準ライブラリに採択されてないのでしょうか
0277デフォルトの名無しさん2012/05/03(木) 06:38:59.61
>>276
無限リストに使うなら、停止するとき返り値は
必ずJust xなんだからfromJustで取り出せば?
0278デフォルトの名無しさん2012/05/03(木) 06:46:35.74
join . liftM :: (r -> r) -> r -> r

これ何の使い道あるんですか?
0279デフォルトの名無しさん2012/05/03(木) 06:57:09.58
>>277
そうでした。。。

コードが汚くなったのは別の改変のせいでした
勘違いして findM 導入のせいにしてました
0280デフォルトの名無しさん2012/05/03(木) 07:10:28.79
>>278
なんの意味もない
liftM使って……て書き込み見たんでliftMから書き始めたからそうなった
今は反省している
0281デフォルトの名無しさん2012/05/03(木) 07:26:28.96
Oh...
0282デフォルトの名無しさん2012/05/03(木) 10:41:16.52
join . liftM p は p :: a -> m Bool を m a -> m b にするのに必要だけど、(>>= p) でも同じ。
0283デフォルトの名無しさん2012/05/03(木) 11:17:28.41
せっかくの話の流れをぶった切って申し訳ないですが、質問します。

正格性フラグの付いたデータ型のことですが、

data X = X !Int
・・・
let x = X a

この場合、x の値が実際に必要になるかどうかに関わらず、
X a の a が評価されるという意味でしょうか。

もうひとつ、

data F = F !(Int -> Int)
・・・
let f = F g

この場合、g が評価されたというのは、どういう状態を指すのでしょうか。
と言うのも、関数ではない値なら弱頭部正規形になるまで評価され、
それがどういった形なのか頭の中にイメージ出来るのですが、
関数の評価という意味がいまひとつイメージ出来ません。

もしかして、g w = if v then 関数1 else 関数2 などと場合分けされていた場合に、
f = F g の時点でこの v まで評価されて関数1か関数2かが決定されるということであり、
単に g w = 2+w などという関数であれば正格性フラグを付ける意味はない、
ということでしょうか。
0284デフォルトの名無しさん2012/05/04(金) 01:11:25.25
>>283
どちらの質問もその考え方であってる。


ただ、わかってるかもしれないけど、

>単に g w = 2+w などという関数であれば正格性フラグを付ける意味はない

束縛された値が正規形なのかとか、リテラルかどうかとか判断する術は一般にないから、
それらを基に正格性フラグ付けることに、意味がある、ないを判断することはできないし、意味もないよ。

重要なのは、値なりデータ構造なりがどこで構築されて、どこで正規化された値が必要になるのか?
0285デフォルトの名無しさん2012/05/04(金) 01:24:42.23
Haskellの道は長く険しい
0286デフォルトの名無しさん2012/05/04(金) 05:16:54.30
なら、やめれば?
言語は道具なんだから、習得に時間や労力が必要なら
その言語は道具として劣っているんだよ。
0287デフォルトの名無しさん2012/05/04(金) 05:52:35.82
つまり習得に時間がかかる日本語や英語は猿のうなり声より劣っていると
0288デフォルトの名無しさん2012/05/04(金) 06:47:05.76
>>283
> この場合、x の値が実際に必要になるかどうかに関わらず、
> X a の a が評価されるという意味でしょうか。
いや、xの値が必要になるまでは評価されない。

> もしかして、g w = if v then 関数1 else 関数2 などと場合分けされていた場合に、
> f = F g の時点でこの v まで評価されて関数1か関数2かが決定されるということであり、
同上。

> 単に g w = 2+w などという関数であれば正格性フラグを付ける意味はない、
> ということでしょうか。
これはそのとおり。
0289デフォルトの名無しさん2012/05/05(土) 03:45:27.77
forM [1..9] print
1
2
:
9
[(),(),(),(),(),(),(),(),()]

この最後のゴミを排除するには
>> return ()
をバインドするのが正統ですか?
0290デフォルトの名無しさん2012/05/05(土) 03:47:18.16
forM_
0291デフォルトの名無しさん2012/05/05(土) 07:28:01.11
あざっす^^
0292デフォルトの名無しさん2012/05/05(土) 13:36:55.17
>>286
C++を窓から放り投げるスレじゃないから
0293デフォルトの名無しさん2012/05/05(土) 22:21:06.18
もしかして、main の中で一行でも IO がつくコードを書いたら、それ以降は絶対に IO は取れないのでしょうか?
02942832012/05/05(土) 23:04:46.88
お二人とも、ありがとうございます。

・・・結局、data X = X !Int の正規化フラグを付けるのと付けないのとで、
何が変わるのでしょうか?

data X = X !Int
・・・
let x = X a

>>284
> どちらの質問もその考え方であってる。

>>288
> いや、xの値が必要になるまでは評価されない。

どちらが正解なんですか。
それとも、お二方も同じ事を言っているのでしょうか。

a の評価のタイミングはいつなんでしょう?


>>284
> 束縛された値が正規形なのかとか、リテラルかどうかとか判断する術は一般にないから、
> それらを基に正格性フラグ付けることに、意味がある、ないを判断することはできないし、意味もないよ。

たしかに。
いや、ライブラリのソースを読んでいて、正規化フラグ付きの関数を持ったデータ型があって、
どういう意図・狙いでフラグを付けたのかなと思いました。
0295デフォルトの名無しさん2012/05/06(日) 02:26:01.72
>>293
main に限らず何かの関数の中で IO を使う関数を利用すれば、その関数の型の出力の部分には絶対に IO が付くという意味なら、 IO は取れない
例外は Debug

もしかして、なにか方法あるのかな?
0296デフォルトの名無しさん2012/05/06(日) 06:18:40.65
>>294
trace付けて確認すればいいやん。

import Debug.Trace

data X = X !Int
data Y = Y Int

main = do
 let x = X (trace "X" 1)
 let y = Y (trace "Y" 2)
 print 3
 print $ seq x 4
 print $ seq y 5
0297デフォルトの名無しさん2012/05/06(日) 11:10:33.37
UnicodeSyntax きもいわー
Scala でもこういうの流行ってるようだし
0298デフォルトの名無しさん2012/05/06(日) 11:19:04.33
さぁその気持ちでAgdaのコードを読もうか
0299デフォルトの名無しさん2012/05/06(日) 12:16:00.88
新人が全角スペースを埋め込んでも怒られない時代
0300デフォルトの名無しさん2012/05/06(日) 12:17:22.58
>>295
一応、標準ライブラリ内に System.IO.Unsafe.unsafePerformIO :: IO a -> a 関数がある

が、これは Simon Marlow と Simon Peyton-Jones の2人以外使ってはいけない
0301デフォルトの名無しさん2012/05/06(日) 15:11:42.01
unsafePerformIO ……それは禁断の果実
0302デフォルトの名無しさん2012/05/08(火) 22:24:51.66
尼のレビュー見てる限りだと、日本語で出てる入門書では
Graham Hutton著・山本和彦訳の「プログラミングHaskell」がいいっぽいけど、実際どうなの?
0303デフォルトの名無しさん2012/05/08(火) 22:27:58.33
実際そう
対抗馬になりそうなのが今月出る「すごいHaskellたのしく学ぼう」
0304デフォルトの名無しさん2012/05/08(火) 22:32:20.78
ゆっくり勉強する時間があるなら、いきなりRWHでいいと思う
0305デフォルトの名無しさん2012/05/09(水) 00:22:24.17
プログラミングHaskellは8章以降が魔窟
0306デフォルトの名無しさん2012/05/09(水) 00:38:56.55
魔窟ってほどではないけどあそこから難易度がすこーんと上がるのは確か
ゾウさん本にはその辺期待してる
0307デフォルトの名無しさん2012/05/09(水) 00:52:04.11
じっくりやるならAlgebra of ProgrammingとかPurely Functional Data Structureみたいな応用の効く(範囲が広すぎて実はあまり役に立たない)内容をですね
0308デフォルトの名無しさん2012/05/09(水) 01:06:20.12
ゾウ本だとHadoopと紛らわしいから愛称が欲しいな
寿司本?
0309デフォルトの名無しさん2012/05/09(水) 01:12:32.86
スゴイ級
0310デフォルトの名無しさん2012/05/09(水) 01:19:18.62
スシボンって書くとセシボンみたいで原題と繋がっていい感じだな
いやなんとなく
0311デフォルトの名無しさん2012/05/09(水) 01:22:38.35
難しいことを簡単に書くのは無理。
0312デフォルトの名無しさん2012/05/09(水) 03:25:04.44
すごハスは11章からが面白い
0313デフォルトの名無しさん2012/05/09(水) 07:14:00.90
すごハスって、基本的にネットで無料で読める原著と内容はほぼ同じ?
それとも、大幅に加筆されてる?
0314デフォルトの名無しさん2012/05/09(水) 08:22:56.77
Real World Haskell P.209に、

fnmatch :: (RegexLike Regex source1) => String -> source1 -> Bool

というのがあります。

ここの(RegexLike Regex source1)というクラス制約にある、A B a という形は
どのようなクラス宣言をすれば、このような形になるのでしょうか?
0315デフォルトの名無しさん2012/05/09(水) 11:56:14.66
ソース読んでみそ。
ttp://hackage.haskell.org/packages/archive/regex-base/latest/doc/html/src/Text-Regex-Base-RegexLike.html

多変数型クラスを宣言するにはMultiParamTypeClassesというLANGUAGEプラグマが必要。
ttp://www.kotha.net/ghcguide_ja/latest/type-class-extensions.html#idp24691328
また、多変数型クラスを含む型推論のために、多くの場合、関数従属または関連型が使われる。
ttp://www.kotha.net/ghcguide_ja/latest/type-class-extensions.html#functional-dependencies
ttp://www.kotha.net/ghcguide_ja/latest/type-families.html#assoc-decl
0316デフォルトの名無しさん2012/05/09(水) 11:57:01.10
ソース読んでみそ。
ttp://hackage.haskell.org/packages/archive/regex-base/latest/doc/html/src/Text-Regex-Base-RegexLike.html

多変数型クラスを宣言するにはMultiParamTypeClassesというLANGUAGEプラグマが必要。
ttp://www.kotha.net/ghcguide_ja/latest/type-class-extensions.html#idp24691328
また、多変数型クラスを含む型推論のために、多くの場合、関数従属または関連型が使われる。
ttp://www.kotha.net/ghcguide_ja/latest/type-class-extensions.html#functional-dependencies
ttp://www.kotha.net/ghcguide_ja/latest/type-families.html#assoc-decl
0317デフォルトの名無しさん2012/05/09(水) 11:59:11.96
しまった。ダブりすまん。
ついでに訂正しておくと、多変数型クラスより多引数型クラスのほうが訳語として一般的みたいだ。
0318デフォルトの名無しさん2012/05/09(水) 12:45:02.58
>>315
d

何故か、hackage.haskell.orgにつながらなくてソースは見られないのですが、
MultiParamTypeClassesというLANGUAGEプラグマをつければ、class宣言に複数の変数を
取ることができるんですね。
0319デフォルトの名無しさん2012/05/11(金) 09:10:35.85
fact 0 = 1
fact n = n * fact (n - 1)
ふと思ったのですが、もし(階乗を知らない人が)負数を突っ込んだら死にますよね。
階乗は例えがアレですけどこういうケースのように、パターンマッチで任意の条件分岐(n < 0とか)できますか?
0320デフォルトの名無しさん2012/05/11(金) 09:16:44.54
直接パターンマッチではできない
if-then-else式を使って、やりたいことはできる、と思う
0321デフォルトの名無しさん2012/05/11(金) 09:17:54.53
あーあと、正しくない結果の時のエラーはundefinedという関数を呼ぶと、
エラーが起きる値が返るから、それを使えばいい
0322デフォルトの名無しさん2012/05/11(金) 09:36:25.12
if-then-elseよかguardの方がよく見る
0323デフォルトの名無しさん2012/05/11(金) 09:41:06.61
ありがとうございます。ガードの方が意味的に良さそうですね。

fact :: Int -> Int
fact (n)
  | (n < 0)  = undefined
  | (n == 0) = 1
  | (n >= 1) = n * fact (n - 1)
0324デフォルトの名無しさん2012/05/11(金) 10:17:08.88
見やすさではそんな感じかな。こだわる人だとこう書くかも
fact n =
 case n `compare` 0 of
  LT -> undefined
  EQ -> 1
  GT -> n * fact (n - 1)
0325デフォルトの名無しさん2012/05/11(金) 10:46:13.79
なるほどcaseならパターンの網羅性もチェックできる訳ですね。
0326デフォルトの名無しさん2012/05/11(金) 10:51:34.61
自分の好みではこう。パターンマッチの上から順に、特殊ケース→一般とする。
fact n | n<0 = undefined
fact 0 = 1
fact n = n * fact (n-1)
0327デフォルトの名無しさん2012/05/11(金) 10:51:35.52
ドメインを広げ過ぎると、また停止性が保証できない問題は出てくるだろうけども。
0328デフォルトの名無しさん2012/05/11(金) 11:11:11.43
tp://www.amazon.co.jp/gp/product/images/4274068854/ref=dp_image_z_0?ie=UTF8&n=465392&s=books

どうしてこうなった…w
0329デフォルトの名無しさん2012/05/11(金) 11:53:25.13
マイナスかどうかのチェックは最初だけでいい、とか言い出すとどうかな
0330デフォルトの名無しさん2012/05/11(金) 15:47:59.33
factSafe = check (>= 0) fact

check p f n = if p n then f n else undefined

fact 0 = 1
fact n = n * fact (n-1)
0331デフォルトの名無しさん2012/05/11(金) 16:13:00.23
わざわざドメイン定義するならMaybeで返そう
■ このスレッドは過去ログ倉庫に格納されています