関数型プログラミング言語Haskell Part18
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2012/03/16(金) 21:54:23.92ttp://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モナド則でこうなってるから
(m >>= f) >>= g == m >>= (\x -> f x >>= g)
0233デフォルトの名無しさん
2012/04/29(日) 17:21:25.38(>>=)は左結合だけどdoは右結合だから問題ない
明示的に(>>=)とラムダを使う場合でも、
a >>= \x ->
b >>= \y ->
c
なら、
a >>= (\x ->
b >>= (\y ->
c))
のことだから、やはり問題ない(ラムダ式は可能な限り右まで続く)
>>232
モナド則は関係ない
0234デフォルトの名無しさん
2012/04/29(日) 18:17:44.38……infixl 1と宣言しておきながら、事実上は右結合なんですか?
右結合って短絡可能なんですよね?
Maybeモナドでは
左にNothingなら問答無用でNothing
ってなってるけど
処理が右結合で、途中Nothingに出逢ったら
Real World Haskellではそのまま最後までNothing伝播処理が続くって書いてあった
でも僕の考える限りでは、右結合では右側が判明するまでの必要最低限の努力をするのが遅延評価だから
途中でNothingに出逢った瞬間からスタック巻き戻しのようになると思うのですが……
/\
/\
/\
N /\
/\
:
/\
/\
/\
/\
N
/\
N
Nothing
0235デフォルトの名無しさん
2012/04/29(日) 19:24:55.15構文の話と意味の話をごっちゃにしてないか
左結合(infixl)というのは、あくまで
a >>= b >>= c
というふうに使ったときに
(a >>= b) >>= c
と解釈される、というだけの意味。それ以外の使い方をした場合には関係ない
後半はその通りで、(Nothing>>=f)はfを呼ばないから、たとえばdoの中でNothing
が出て来たらそれ以降は評価すらしない
そのNothingが別のdo(呼び出し元の関数とか)に渡ったときには
Nothingの伝播処理が挟まる
0236デフォルトの名無しさん
2012/04/29(日) 21:27:11.79質問@
Maybe 上で (>>=) あるいは (>>) を使ってたくさんの計算を連鎖するとき、
その計算のどれかが Nothing を返したら、残りの計算は一切評価されません。
しかしこの連鎖は完全には短絡されていないことに注目しましょう。
連鎖中のそれぞれの (>>=) や (>>) は左の Nothing にマッチすると右に Nothing を生成し、
最後までそうしていきます。この点は忘れやすいものです。
連鎖中の計算が失敗したとき、それに続くNothing 値の生成、連鎖、消費は実行時に安価ではありますが、タダというわけではありません。
348 P にこう書いてありますが、私にはこの文脈が左結合を示唆しているかのように見受けられます。つまりは、
/\
/\
/\
N
/\
/\
N
/\
N
Nothing
こう主張しているように思えるのです。短絡は起きていないように思えます。
ここで私のいう短絡とは、関数処理のスキップのみならず木構造の一発切除をも意味します
Nothingに出逢った瞬間全てを忘れて即Nothingです
これは無理なのでしょうか?
0237デフォルトの名無しさん
2012/04/29(日) 21:31:47.75質問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.070240デフォルトの名無しさん
2012/04/30(月) 03:31:17.360241デフォルトの名無しさん
2012/04/30(月) 09:20:17.79「信用」の意味がよく分らないです
Haskell は初心者から、本来あるべきどのような信用がないのでしょうか
0242デフォルトの名無しさん
2012/04/30(月) 09:55:23.07くっそこんなので笑わされるとは
0243デフォルトの名無しさん
2012/04/30(月) 10:03:34.530244デフォルトの名無しさん
2012/04/30(月) 11:13:59.36例えばリテラルからの暗黙の型変換は一部ありますよね
Num.fromInteger 関数とか IsString.fromString 関数を定義しておけば、
リテラル整数や文字列を適切な型にコンパイラが自動的に変換してくれる
(後者は GHC の拡張機能ですが)
これの延長で、例えば OpenGL を使っていて、
GLdouble 型を引数に取る関数を Double 型に適用しようとした時、
何か特別な定義をしておけば、realToFrac 関数を使わずとも、
コンパイラが自動的に変換してくれるとか
このような例だけでなく、一般的に fromIntegral 関数とか realToFrac 関数って、
けっこう目障りなんですよね
これらって、型推論出来るようにコードを書かなければならないという、
どちらかと言うと言語仕様よりの概念じゃないですか
そのわりに、realToFrac 関数だけでは、ぱっと見、何から何への変換か分らない
一方で、これらの関数が使われているコードは、
何を計算するのかという、もっと抽象度の高い概念をコード化しているわけで
抽象度の高いコードの中に、抽象度の低い「おまじない」の様なコードが
けっこう大きな石ころのように混ざっている状況が、なんとも違和感を覚える
どうにかならないものでしょうか
0245デフォルトの名無しさん
2012/04/30(月) 11:26:54.17うーん、言語の設計者より自分の方が頭いいかもしんない、と思われちゃってるところ。
0246デフォルトの名無しさん
2012/04/30(月) 11:45:17.37抽象度とか言いつつ全体が見えていない
0247デフォルトの名無しさん
2012/04/30(月) 11:57:23.83有難うございました(´;ω;)
0248デフォルトの名無しさん
2012/04/30(月) 14:53:15.43上を押しても同じ履歴だった場合、動いてないように見えてストレスとなります
0249デフォルトの名無しさん
2012/04/30(月) 15:06:17.22残念ながら現状ではどうにもならない
なにかストレスを発散する方法を考えてくれ
0250デフォルトの名無しさん
2012/04/30(月) 15:30:36.770251デフォルトの名無しさん
2012/04/30(月) 18:34:46.960252デフォルトの名無しさん
2012/04/30(月) 18:36:44.310253デフォルトの名無しさん
2012/04/30(月) 18:38:36.110254デフォルトの名無しさん
2012/04/30(月) 23:24:32.160255デフォルトの名無しさん
2012/04/30(月) 23:33:00.05・どうやってボタン表示するんですか
・ループが出来ません
・変数変えれないんですけど
そんな質問しねーよ、って人ならもう初心者じゃない
具体的に「Haskellでやりたいこと」を見つけて取り組んでくれ
分かんないことがあったらピンポイントで質問してこい
あたしらが優しく相手してやる
0256デフォルトの名無しさん
2012/05/01(火) 00:09:38.80今生きているHaskellのGLRパーサはありませんか?
0257デフォルトの名無しさん
2012/05/01(火) 03:16:34.46お、お前……女だったのか……。
0258デフォルトの名無しさん
2012/05/01(火) 03:22:27.79具体的には今あるコード資産に対してコード変換して,機能拡張したい,
そのための便利な仕組みない
0259デフォルトの名無しさん
2012/05/01(火) 04:32:54.50いんや?
自分が初心者の頃、親切に教えてもらったぞ?
プログラミングHaskellで最初に詰まって、散々悩んだreplicateのリスト内包表記版を作れって問題とか
初心者でも、replicateの再起版はすぐに思いついたんだが、この頃は本当に頭が固かったな・・・
(ヒントがlengthのリスト内包表記版の応用って書かれてても、全然思い浮かばんかった)
回答してもらって、ああ、なるほど、lengthのリスト内包表記版の応用だ。ってやっと納得できたっけ
そもそもHaskellはRubyとかと違って、組込み関数も自分で簡単に作れるってのが初心者の頃の自分には言語の理解の助けになった
普段自分の使ってる関数の動きを自分で同じ関数作って確認しながら覚えられるから、あんまり基本的過ぎる質問ってする必要が無かったし、
>>255同様、初心者らしい質問って、そもそもHaskell(または関数型言語)ってどんな言語?とか以外じゃ見ない(それも最初のスレだけだったような・・・)
当時の自分の質問が一番初心者らしい質問だったと思う
0260デフォルトの名無しさん
2012/05/01(火) 06:00:09.93深さ優先探索なので,(1,1)の後は事実上フリーズします
これを深さも幅も均衡して広げて探索していくにはどうしますか?
0261デフォルトの名無しさん
2012/05/01(火) 06:38:12.34[(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昔のことは知ってるよ。Part3くらいから居る
>>231を馬鹿にする流れを見て、正気か?と思っただけ
0263デフォルトの名無しさん
2012/05/01(火) 09:44:02.400264デフォルトの名無しさん
2012/05/01(火) 15:45:08.13面白いハックです
ありがとうございました
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後者です
findでやってみようと思ったんですが
術語が Int -> IO Bool なんです
filterM みたいに findM があればいいと思いますが
filterMしてheadって不格好です
きっとスマートな解決法がある筈です
0268デフォルトの名無しさん
2012/05/02(水) 22:03:05.12無限のモナドのリストを渡すとフリーズしますよね
最初、遅延評価なのになんで正格評価みたいになってんだと首を傾げたのですが
考えてもみれば、順序を保証するんだからfilterMに無限のモナドのリストを渡すと
そのリストの最後の評価が済むまで次の行けないですよね
困りました
0269デフォルトの名無しさん
2012/05/02(水) 22:20:28.350270デフォルトの名無しさん
2012/05/02(水) 22:54:51.28どうもならん、諦めろ
0271デフォルトの名無しさん
2012/05/02(水) 23:45:26.550272デフォルトの名無しさん
2012/05/03(木) 00:06:04.51find p = listToMaybe . filter p
だぞ。別に filterM して head も似たようなもんじゃないか?
[IO a]でもIO [a]でも無限リストで要素が無ければ止まらないのは
一緒だと思う。
0273デフォルトの名無しさん
2012/05/03(木) 00:27:44.81はい(´・ω・`)
0274デフォルトの名無しさん
2012/05/03(木) 00:29:59.11これは要素があっても[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ありがとうございました
filterMに倣って
findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
版を作って使ってみましたが、何だかソースが汚れた気がします
Maybeを取扱う為に一々letやcaseを挿入しないとならなくなったせいでしょうね
しょうがないでしょうが
ところで何故標準ライブラリに採択されてないのでしょうか
0277デフォルトの名無しさん
2012/05/03(木) 06:38:59.61無限リストに使うなら、停止するとき返り値は
必ずJust xなんだからfromJustで取り出せば?
0278デフォルトの名無しさん
2012/05/03(木) 06:46:35.74これ何の使い道あるんですか?
0279デフォルトの名無しさん
2012/05/03(木) 06:57:09.58そうでした。。。
コードが汚くなったのは別の改変のせいでした
勘違いして findM 導入のせいにしてました
0280デフォルトの名無しさん
2012/05/03(木) 07:10:28.79なんの意味もない
liftM使って……て書き込み見たんでliftMから書き始めたからそうなった
今は反省している
0281デフォルトの名無しさん
2012/05/03(木) 07:26:28.960282デフォルトの名無しさん
2012/05/03(木) 10:41:16.520283デフォルトの名無しさん
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どちらの質問もその考え方であってる。
ただ、わかってるかもしれないけど、
>単に g w = 2+w などという関数であれば正格性フラグを付ける意味はない
束縛された値が正規形なのかとか、リテラルかどうかとか判断する術は一般にないから、
それらを基に正格性フラグ付けることに、意味がある、ないを判断することはできないし、意味もないよ。
重要なのは、値なりデータ構造なりがどこで構築されて、どこで正規化された値が必要になるのか?
0285デフォルトの名無しさん
2012/05/04(金) 01:24:42.230286デフォルトの名無しさん
2012/05/04(金) 05:16:54.30言語は道具なんだから、習得に時間や労力が必要なら
その言語は道具として劣っているんだよ。
0287デフォルトの名無しさん
2012/05/04(金) 05:52:35.820288デフォルトの名無しさん
2012/05/04(金) 06:47:05.76> この場合、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.771
2
:
9
[(),(),(),(),(),(),(),(),()]
この最後のゴミを排除するには
>> return ()
をバインドするのが正統ですか?
0290デフォルトの名無しさん
2012/05/05(土) 03:47:18.160291デフォルトの名無しさん
2012/05/05(土) 07:28:01.110292デフォルトの名無しさん
2012/05/05(土) 13:36:55.17C++を窓から放り投げるスレじゃないから
0293デフォルトの名無しさん
2012/05/05(土) 22:21:06.180294283
2012/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.72main に限らず何かの関数の中で IO を使う関数を利用すれば、その関数の型の出力の部分には絶対に IO が付くという意味なら、 IO は取れない
例外は Debug
もしかして、なにか方法あるのかな?
0296デフォルトの名無しさん
2012/05/06(日) 06:18:40.65trace付けて確認すればいいやん。
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.37Scala でもこういうの流行ってるようだし
0298デフォルトの名無しさん
2012/05/06(日) 11:19:04.330299デフォルトの名無しさん
2012/05/06(日) 12:16:00.880300デフォルトの名無しさん
2012/05/06(日) 12:17:22.58一応、標準ライブラリ内に System.IO.Unsafe.unsafePerformIO :: IO a -> a 関数がある
が、これは Simon Marlow と Simon Peyton-Jones の2人以外使ってはいけない
0301デフォルトの名無しさん
2012/05/06(日) 15:11:42.010302デフォルトの名無しさん
2012/05/08(火) 22:24:51.66Graham Hutton著・山本和彦訳の「プログラミングHaskell」がいいっぽいけど、実際どうなの?
0303デフォルトの名無しさん
2012/05/08(火) 22:27:58.33対抗馬になりそうなのが今月出る「すごいHaskellたのしく学ぼう」
0304デフォルトの名無しさん
2012/05/08(火) 22:32:20.780305デフォルトの名無しさん
2012/05/09(水) 00:22:24.170306デフォルトの名無しさん
2012/05/09(水) 00:38:56.55ゾウさん本にはその辺期待してる
0307デフォルトの名無しさん
2012/05/09(水) 00:52:04.110308デフォルトの名無しさん
2012/05/09(水) 01:06:20.12寿司本?
0309デフォルトの名無しさん
2012/05/09(水) 01:12:32.860310デフォルトの名無しさん
2012/05/09(水) 01:19:18.62いやなんとなく
0311デフォルトの名無しさん
2012/05/09(水) 01:22:38.350312デフォルトの名無しさん
2012/05/09(水) 03:25:04.440313デフォルトの名無しさん
2012/05/09(水) 07:14:00.90それとも、大幅に加筆されてる?
0314デフォルトの名無しさん
2012/05/09(水) 08:22:56.77fnmatch :: (RegexLike Regex source1) => String -> source1 -> Bool
というのがあります。
ここの(RegexLike Regex source1)というクラス制約にある、A B a という形は
どのようなクラス宣言をすれば、このような形になるのでしょうか?
0315デフォルトの名無しさん
2012/05/09(水) 11:56:14.66ttp://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.10ttp://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.58d
何故か、hackage.haskell.orgにつながらなくてソースは見られないのですが、
MultiParamTypeClassesというLANGUAGEプラグマをつければ、class宣言に複数の変数を
取ることができるんですね。
0319デフォルトの名無しさん
2012/05/11(金) 09:10:35.85fact n = n * fact (n - 1)
ふと思ったのですが、もし(階乗を知らない人が)負数を突っ込んだら死にますよね。
階乗は例えがアレですけどこういうケースのように、パターンマッチで任意の条件分岐(n < 0とか)できますか?
0320デフォルトの名無しさん
2012/05/11(金) 09:16:44.54if-then-else式を使って、やりたいことはできる、と思う
0321デフォルトの名無しさん
2012/05/11(金) 09:17:54.53エラーが起きる値が返るから、それを使えばいい
0322デフォルトの名無しさん
2012/05/11(金) 09:36:25.120323デフォルトの名無しさん
2012/05/11(金) 09:41:06.61fact :: Int -> Int
fact (n)
| (n < 0) = undefined
| (n == 0) = 1
| (n >= 1) = n * fact (n - 1)
0324デフォルトの名無しさん
2012/05/11(金) 10:17:08.88fact n =
case n `compare` 0 of
LT -> undefined
EQ -> 1
GT -> n * fact (n - 1)
0325デフォルトの名無しさん
2012/05/11(金) 10:46:13.790326デフォルトの名無しさん
2012/05/11(金) 10:51:34.61fact n | n<0 = undefined
fact 0 = 1
fact n = n * fact (n-1)
0327デフォルトの名無しさん
2012/05/11(金) 10:51:35.520328デフォルトの名無しさん
2012/05/11(金) 11:11:11.43どうしてこうなった…w
0329デフォルトの名無しさん
2012/05/11(金) 11:53:25.130330デフォルトの名無しさん
2012/05/11(金) 15:47:59.33check 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■ このスレッドは過去ログ倉庫に格納されています