関数型プログラミング ..
[2ch|▼Menu]
75:デフォルトの名無しさん
04/02/22 18:59
>>74
> 「関数のn乗」 -> ない。

なぜないんでしょう,あってもよさそうなのに。

> chop -> init

ありがとう。では直しておきます。

f n xs = (iterate init $ map (take n) $ tails xs) !! n

これは無限リストで大丈夫ですね。

> 新しい良いアイディアが含まれていなかったり、
> 明らかに良くない方法だったりするものを
> 無闇に書き込むのは止めないか?(せめて欠点を併記するとか)

欠点を併記するというのはいいですね。でも,今まで前を拾うこ
とばかりしいたから,今度は後ろを落としてみたらどうかという
発想なので「無闇に」というのとは違いますよ。

76:デフォルトの名無しさん
04/02/22 19:20
> 「関数のn乗」
手許に処理系ないんだけど、foldl とか (.) とかで簡単に作れそうな。

77:74
04/02/22 20:18
>>75  
> 発想なので「無闇に」というのとは違いますよ。
失礼。
あなただけに書いたわけではなくて、>>70-71などを指していた。

> 「関数のn乗」
(iterate f x) !! n が普通なんだろうけど、
自分でtail recursiveな
nest :: (a -> b) -> a -> Int -> b
nest' :: (a -> b) -> a -> Int -> b  -- strict
あたりを書いたほうが、速くていいね。
標準にあったほうがいいというのに同意。

> 手許に処理系ないんだけど、foldl とか (.) とかで簡単に作れそうな。
foldlは無駄な処理をするのでまずい。
composition f n = foldr (.) id $ replicate n f
あたりか。

78:74
04/02/22 20:18
最後は>>76宛。

79:74
04/02/22 20:19
なんどもすまん。
  nest :: (a -> a) -> a -> Int -> a
だね。

80:デフォルトの名無しさん
04/02/23 21:34
>>77
> 標準にあったほうがいいというのに同意。
ですよね。標準でないのは f^n は複数の n に対して評価する
可能性があるのでリストにキャッシュしておけ,という主張か
とも思ったのですが。あっても悪くない気がします。


f n xs = (transpose $ map inits $ tails xs) !! n
(制限:n は xs のサイズ以下,無限リスト可)

81:デフォルトの名無しさん
04/02/29 06:43
なんとなくテクニックの紹介をしてみる。

Haskellのリストは一つの型しか保持できない。
しかし、複数の型であっても、その間に「関係」があれば、
それらの型をラップし、一つのリストにいれた上で使用することができる。
--------------
{-# OPTIONS -fglasgow-exts #-}
-- different types
data A = A String deriving Show
methA (A x) = length x
data B = B Int deriving Show
methB (B x) = x
-- but they have the methods of the same return type Int
data C = forall x. C x (x -> Int)
runC (C x f) = f x
testC = map runC [C (A "I am A") methA, C (B 100) methB]
-- if they belong to the same type class
data ShowC = forall x. (Show x) => ShowC x
instance Show ShowC where
    show (ShowC x) = show x
testShowC = show [ShowC $ A "I am A", ShowC $ B 100]
-- nearly nonsense
data X = forall x. X x

82:デフォルトの名無しさん
04/03/03 22:00
sage

83:デフォルトの名無しさん
04/03/23 15:38
GHC-6.2.1 released

84:デフォルトの名無しさん
04/03/23 22:23
Functional Programming With Haskell
URLリンク(www.amazon.com)

久々の新刊かも

85:デフォルトの名無しさん
04/03/23 22:46
>>84
豪快に割引されてますな。


86:デフォルトの名無しさん
04/03/23 22:49
前スレでガイシュツだったのか。
スレリンク(tech板) #554
一年以上も前に。

87:デフォルトの名無しさん
04/03/24 12:00
wxHaskell使ってる人っている?

88:デフォルトの名無しさん
04/03/24 16:27
>>84
ペーパーバックで5000円か…

89:デフォルトの名無しさん
04/03/25 06:54
>>87
できあがる実行ファイルがでかすぎる

90:デフォルトの名無しさん
04/03/30 23:30
>>89
Minimulコードでどれぐらい?

91:デフォルトの名無しさん
04/03/31 02:56
>>90
@ Mac OS X 10.3

--- Hello.hs
module Main where
import Graphics.UI.WX

main :: IO ()
main = start hello

hello :: IO ()
hello =
   do
    f <- frame [text := "Hello world!"]
    quit <- button f [text := "Quit", on command := close f]
    set f [layout := widget quit]
---

$ ghc -package wx -o hello Hello.hs

で、helloのサイズが7M強。

92:デフォルトの名無しさん
04/03/31 17:53
stripして3M弱だな。

93:デフォルトの名無しさん
04/04/03 19:31
そりゃすげえな

94:デフォルトの名無しさん
04/04/03 19:37
よくしんねぇけど、
ツールキット全部そんなかに入ってんじゃないの?
だったら仕方ねぇと思うけど。
外出しには出来ねぇのかな?

95:デフォルトの名無しさん
04/04/07 21:00
GHC を ports の導入されていない FreeBSD に導入したいんだが
どうすればいいのだろう?

96:デフォルトの名無しさん
04/04/07 21:11
make install

97:デフォルトの名無しさん
04/04/07 21:13
a) portsを入れてmake install
b) packageを持ってきてpkg_add


98:デフォルトの名無しさん
04/04/07 21:47
みんなまずインタプリタで開発して、
安定してきてリリースする間際にコンパイラに移行するの?
インタプリタで正常動作してるけど、コンパイラではうまく動かないってこと多い?
Haskellってコンパイル撃遅い(というか長い)ッてきいたけどマジ?

99:デフォルトの名無しさん
04/04/07 22:07
>>96
GHC のコンパイルには GHC バイナリが必要です

>>97
ports や package は教育上入れてもらえない学生さんなんですよ

100:デフォルトの名無しさん
04/04/08 14:25
>>99
FreeBSD の ftp サーバの ports/distfiles に
ghc-<version>-i386-unknown-freebsd-boot.tar.bz2 があるからこれを展開して,
ghc のコンパイル時にこの展開先にある ghc を指定してコンパイルすればok.

ちなみに ports も同じことをしている(処理が自動化されてるだけ).

>>98
コンパイルはたしかに激遅.
プログラマが楽するためにコンピュータに頑張ってもらってる感があるね.

101:デフォルトの名無しさん
04/04/08 15:40
マニュアル印刷したいんだけど、1枚のHTMLにしてくんないかな。印刷しづらい。
URLリンク(www.sampou.org)


102:デフォルトの名無しさん
04/04/08 15:53
>>101
そんなのちょこっとスクリプト走らせれば楽勝だろ?

103:デフォルトの名無しさん
04/04/08 19:12
>>98
> みんなまずインタプリタで開発して、
おれはそうしてる。GHCiでときどきHugsでチェック。

> インタプリタで正常動作してるけど、コンパイラではうまく動かないってこと多い?
そんな経験は無い。

104:デフォルトの名無しさん
04/04/08 20:10
>>100
ありがとう

試してみてうまくいったらまた報告します

105:デフォルトの名無しさん
04/04/08 22:55
NHCの方が良質のコードを生成するって聞いたことあるけど、
もう今は昔の話なのかな?

106:デフォルトの名無しさん
04/04/08 23:14
このスレでも聞いてみる。
Scheme,OCaml,Haskell,Clean、覚えて「損しない」「一番得」
な言語はどれ。ぶっちゃけ周辺ライブラリーが充実してるのどれ。

107:デフォルトの名無しさん
04/04/08 23:20
>>106
得するのは、全部覚えること。
得しないのは、ひとつしか覚えないこと。

108:デフォルトの名無しさん
04/04/08 23:54
>>106
若いなら全部やれ

109:デフォルトの名無しさん
04/04/09 00:27
>>105
コンパイルは速いけどね。
Hugs/GHC共通のHierachical moduleの多くが使えないのが痛すぎる。

今試しに
main = interact id
をnhc98(FreeBSD-CURRENT, from ports)でコンパイルしたらbus error....

110:デフォルトの名無しさん
04/04/09 00:34
r抜けてたHierarchical

111:デフォルトの名無しさん
04/04/12 16:54
>>106
統計やるならRが結構ナイスだ。

112:デフォルトの名無しさん
04/04/12 22:37
>>110-111
Rスレはこっちに↓あ〜る

= 統計解析フリーソフト R =
スレリンク(math板)

113:デフォルトの名無しさん
04/04/14 12:02
工科大の
URLリンク(www.teu.ac.jp)
の問題1 ですが、

> sigma :: (Int -> Int) -> (Int -> Int)
> 上記の関数sigmaを,1) ラムダ記法を使って,2) 関数の部分適用を使って,定義せよ.ただし,sigma fは,自然数nに対して
> f 0 + f 1 + ... + f n
> を計算する関数とする.

lambda 版 は以下のように作成しました。
sigmaLambda :: (Int -> Int) -> (Int -> Int)
sigmaLambda f = \x -> sum [f i | i <- [0 .. x]]

で、部分適用版ですが、

sigma :: (Int -> Int) -> Int -> Int
sigma f 0 = f 0
sigma f n = sigma f (n-1) + f n

で、いいんでしょうか。
題意のような関数を返すのですが、部分適用という感じがしません。
出題者がどのような回答を期待しているか知りたいのですが。
(あと、なんか lambda版を、内包表現とか使ってて、出題意図に沿ってないような気がするのです)

114:デフォルトの名無しさん
04/04/14 13:37
>>113
> 題意のような関数を返すのですが、部分適用という感じがしません。
addNum'' n m = n + m に部分適用を使ったといっているのだからそれでいいだろう。
sigmaPartial f n = sum [f m | m <- [0..n]]

> (あと、なんか lambda版を、内包表現とか使ってて、出題意図に沿ってないような気がするのです)
それなら使わなければいいのでは?
sigmaLambda = \f n -> if n == 0 then f 0 else sigmaLambda f (n - 1) + f n

115:デフォルトの名無しさん
04/04/14 14:00
sigma,sigma' :: (Int -> Int) -> (Int -> Int)
sigma f = \ n -> foldl (\ s i -> s + f i) 0 [0..n]
sigma' f = let iter s x = if x < 0 then s else iter (s+f x) (x-1) in iter 0

116:デフォルトの名無しさん
04/04/14 14:37
import Control.Monad.Fix (fix) -- fix f = f (fix x)
sigma = flip fix 0 $ \s t f n -> if n < 0 then t else s (t + f n) f (n - 1)

117:デフォルトの名無しさん
04/04/14 14:38
fix f = f (fix f)ね。

118:デフォルトの名無しさん
04/04/19 19:21
Haskell に例外処理の機構はあるの?

119:デフォルトの名無しさん
04/04/19 19:37
ある。
Haskell98でもIOモナドからthrowできる例外(IOError)があるし、
最近のGHC、Hugsでは普通の関数からも例外(Exception)をthrowできる。
catchはIOモナドの中でおこなう。

参照: Control.Exception

120:デフォルトの名無しさん
04/04/20 23:50
Haskell勉強中なんですけど、
「モナドは継続渡しを提供する」という大雑把な理解でいいでしょうか?
・・・違うかな?

121:デフォルトの名無しさん
04/04/24 22:23
なんで Prelude で (!!) は Integer じゃなくて Int で定義されているの?

122:デフォルトの名無しさん
04/04/25 02:07
>>121
実際問題それ以上使うことはないからだろう。
Haskell 98 Report によると maxBound::Int は少なくとも 2^29-1。
(!!)のインデックスは0-originだから、長さ2^29のリストまで扱える。
これ以上の長さのリストを使う場面は……。

123:デフォルトの名無しさん
04/04/25 12:41
円周率の世界記録に朝鮮したい人はどうすれば?

124:デフォルトの名無しさん
04/04/25 18:11
>>123
自分で最低義すれ。

125:デフォルトの名無しさん
04/04/26 14:54
>>123
円周率は全桁保持していなくても次を計算できたはず。

>>124
アドレスの制限があるから多くの計算機と既存の処理系では
再定義しても無駄。

126:デフォルトの名無しさん
04/04/26 23:48
>>120 こんなん見つけた

URLリンク(www.jaist.ac.jp)

ここの資料はjaistのゼミ資料?
他にはHaskellDBが自分的に興味深い.
TorqueとかHibernateなんて目じゃない. Haskellだけど…

127:デフォルトの名無しさん
04/04/27 14:27
>>121
haskell@でもちょうど議論されてるね。
上ででたものの他に、こういう意見があった。

Integer派:
*   Lazyにcreated/destroyedなデータならアドレスの制限を
    受けずに大きいものを利用できるはずだ。
*   Intは一般的なケースへの最適化であり、
    "Premature optimization is the root of all evil."

Integerには反対派:
    Integerにするのは、巨大なリストという特殊な状況への最適化である。
    (Integral b) => がよろしい。

128:デフォルトの名無しさん
04/04/27 18:46
Hanatani さんすげーな。
オレもああいう凄腕Haskellerになりたい。

129:デフォルトの名無しさん
04/04/28 12:39
>>128
なんか凄いもの作ったの?

130:デフォルトの名無しさん
04/05/05 01:32
しばらく見ないうちに「関数型言語」のスレがひどいことになってるな。


131:デフォルトの名無しさん
04/05/05 02:34
>>130
Aranskさま〜〜早くこのスレにも御光臨してくださいませ〜〜
Aranskさま〜〜早くこのスレにも御光臨してくださいませ〜〜
Aranskさま〜〜早くこのスレにも御光臨してくださいませ〜〜
Aranskさま〜〜早くこのスレにも御光臨してくださいませ〜〜
Aranskさま〜〜早くこのスレにも御光臨してくださいませ〜〜

132:デフォルトの名無しさん
04/06/27 22:34
たま〜にはあげてみる

Haskell Support for the Eclipse IDE
URLリンク(eclipsefp.sourceforge.net)

0.3.0はEclipse最新var.(M9〜正式版)に対応しているぞ。

133:デフォルトの名無しさん
04/06/30 18:10
おお. しかしスクリーンショットがほしい所かも. 後でインスコしてみるか…

Fudgets
URLリンク(www.cs.chalmers.se)

触ってる人いる? これから弄ってみようと思うのだけど.

featureのページに,
Declarative flavour. While it is possible to enable GUI programming in
a functional language by providing an interface to an imperative GUI toolkit and,
in effect, using an imperative sub-language within the functional language,
Fudgets provide a declarative style of programming also for the construction of GUIs.

とある. なんだか期待大.

134:デフォルトの名無しさん
04/06/30 20:48
>>133
使えたら是非おしえてくれ。
Declarative GUI toolkitって数年前から
どれもメンテが止まってるっぽいんだよな。

最近ではwxHaskellがスタンダードになりつつあるけど、
やっぱりHaskellならDeclarativeにやりたい。

135:デフォルトの名無しさん
04/07/17 08:42
Haskell Marathon
URLリンク(www.sampou.org)

136:デフォルトの名無しさん
04/07/18 09:25
Haskell で Marathon を実装するのかとオモタ。

137:デフォルトの名無しさん
04/07/26 01:14
マラソン参加してみようかな。入門ページ読んだくらいで準備はよいだろうか

138:デフォルトの名無しさん
04/07/29 09:20
マラソン直前に台風直撃の悪寒

139:デフォルトの名無しさん
04/08/09 23:33
LL WeekendでのHaskellに対する聴衆の感想は「Haskellのコードはよくわからない」というのが多かったみたいでつね

140:デフォルトの名無しさん
04/08/10 01:19
5分だか7分だかでわかれという方が無理があるという話がある。発表者陣はよ
くやったと思うよ。
「わたしはもうループも書けなくなってしまって……」というのにワロタ。

141:デフォルトの名無しさん
04/08/11 02:33
LL侍はHaskellを斬ったの?

142:デフォルトの名無しさん
04/08/12 01:39
>>141
「Hello, worldもブラックボックス斬り」されてました。

143:デフォルトの名無しさん
04/08/12 13:41
おれはhaskell haskell haskellだ
関数型の haskellだ
短くて 簡潔で 理解しやすいコードを書けるぜ
って、言うじゃない

だけど
難しくて monad が理解できませんから

残念!
「Hello worldさえブラックボックス」
斬り

144:デフォルトの名無しさん
04/08/12 20:55
むしろHello, worldだから難しいような気がする


145:デフォルトの名無しさん
04/08/12 21:58
main = do putStr "Hello, World!"

で済むから、コード自体は特に難しくは見えない。
ただ、入門者が Hello, World に到達するまでの過程が難しいんだよね……。


146:デフォルトの名無しさん
04/08/12 22:00
>>145
そのdoはいるの?

147:145
04/08/12 23:13
この場合はいらないけど、先々のことを考えたら入れた方がいいかな、とちょっ
とだけ思ったのです。
main = do str <- getLine
putStr str
みたいに。


148:デフォルトの名無しさん
04/08/13 07:57
いきなりIOから入るのがまずい。
fact→fib→qsortあたりから入れば
得体の知れないモナドをとりあえず回避できる。

149:デフォルトの名無しさん
04/08/13 16:25
再帰とリスト処理しかできないHaskellちゃん
がんばってもせいぜい二分木

150:デフォルトの名無しさん
04/08/13 17:34
膣門です。
"Hindley-Milner" って、何て読むんでつか?


151:デフォルトの名無しさん
04/08/14 01:49
誰か「モナドだけで書く Haskell プログラミング」を書いてくれい

152:デフォルトの名無しさん
04/08/15 13:29
>>151 Cでも使ってれば?

153:デフォルトの名無しさん
04/08/15 21:34
そういやHaskellのコンパイルはC経由なんだよね

154:デフォルトの名無しさん
04/08/15 22:04
末尾再帰の保証とかC経由じゃ無理だろ

155:デフォルトの名無しさん
04/08/15 22:21
GHCで最適化オプション付けるとCのコード吐くんじゃなかったっけ?

156:デフォルトの名無しさん
04/08/16 02:59
>>150
メール出して聞いたら?
URLリンク(www-maths.swan.ac.uk) J. Roger Hindley
URLリンク(www.cl.cam.ac.uk) Robin Milner

157:デフォルトの名無しさん
04/08/16 05:57
>>156
もちつけ

158:デフォルトの名無しさん
04/08/16 06:12
>>154
そりゃ当然、Cにする前にプログラム変換するだろ
それに大抵のCCには-foptimize-sibling-callsみたいなのがあるだろうし

159:デフォルトの名無しさん
04/08/16 08:24
レベル低いな。っつってもHaskellのことは何も知らないのであれなんだが。。。
ユーザーレベルで言語をマスターするっつーのは、ある処理系を骨までしゃぶり
尽くすことだろ。リスパーのように自作こそ最強だが、複雑な言語ではそこまでは
まあ、なかなか出来るもんでもないしな。
GHCのことについて詳しい奴がいないのを見ると、誰もHaskellでまともに
プログラム書こうとしてないように見える。結局おまいらは、話のネタに
関数型言語を選んでるだけなんだよ。

160:デフォルトの名無しさん
04/08/16 23:20
↑Aransk?

161:デフォルトの名無しさん
04/08/17 00:31
Simon Peyton Jones は C-- もやってるのに、自前でオプティマイズ出来ないってのは意外。

162:デフォルトの名無しさん
04/08/17 00:50
>160
Aranskはいちゃもん言うだけでプログラムすら書かんだろ?

163:デフォルトの名無しさん
04/08/18 12:47
wxhaskellについてですが、
サンプルプログラムのBouncingBalls.hsでセグメンテーションフォールトが
起きます。(URLリンク(wxhaskell.sourceforge.net))
プログラムを起動し、'p'などのアルファベットを入力することで生じます。

そこで小さなプログラムを作って試してみたのですが、
やはり同様な現象が起ります。

$ cat test.hs
import Graphics.UI.WX

main :: IO ()
main = start test

test :: IO ()
test = do f <- frame []
p <- panel f []
set f [layout := widget p]
set p [on(charKey 'a') := print "test ok"]
$ ghc -package wx test.hs -o test
$ ./test
(ここでキーボードの'a'を入力)
セグメンテーション違反です

環境
wxhaskellのバージョンは0.7
wxGTKのバージョンは2.4.2
OSはlinux

他の環境でもこのバグが再現するでしょうか。

164:デフォルトの名無しさん
04/08/19 17:20
>>163
特に問題発生せず

環境
wxHaskell 0.8
wxWidget 2.5.2
MacOS X 10.3

$ ghc -package wx test.hs -o test
$ /usr/local/wxhaskell/bin/macos-app -v test

できたtestをFinderからダブルクリックで起動
真っ白いパネルが出てくる
'a' 押すと「コンソール」に "test ok"

とりあえずバージョンアップしてみれば

165:デフォルトの名無しさん
04/08/22 09:05
wxHaskellを0.8にバージョンアップしたら問題は解決しました。
どうもありがとうございます。

166:デフォルトの名無しさん
04/08/22 09:36
このような関数はどう書けばいいんでしょうか?

f (+) [1 2 3] [4 5 6] => [5 7 9]

167:デフォルトの名無しさん
04/08/22 11:30
f g (x:xs) (y:ys) = (g x y) : f g xs ys

168:デフォルトの名無しさん
04/08/22 11:41
f g xs ys = [g x y | (x, y) <- zip xs ys]

169:デフォルトの名無しさん
04/08/22 11:55
これを拡張したn引数(n階?)の関数とn個のリストをとる
関数はどう書くのがいいでしょう。

f n g [x11, x12, ...] [x21, x22, ...] ... [xn1, xn2, ...]
=> [(g x11 x21 ... xn1), (g x12 x22 ... xn2), ...]

みたいな。lispのmapってこんな感じですよね。あちらは
関数のarityがわかるからnは不要ですけど。


170:デフォルトの名無しさん
04/08/22 12:19
f g = map (hoge g) $ zip
Haskellはよく知らんので、hogeをどうやって書くのか調べてもよく分からん。

171:デフォルトの名無しさん
04/08/22 16:24
引数の数が可変ってhaskellでは書けないような気が。
何か方法あったっけ?

172:デフォルトの名無しさん
04/08/22 16:45
>>166

zipWith (+) [1, 2, 3] [4, 5, 6]

173:デフォルトの名無しさん
04/08/22 17:19
>>171
別に可変個の引数は必要ない。
1引数の関数のリストと引数のリストを受け取って適用して返す演算子をつくればOK。
演算子をxとすると
[f, f, f] x [x11, x12, x13] x [x21, x22, x23]
とか。Haskellの細かい文法知らんのでこう書けるかどうかは知らないけど。


174:デフォルトの名無しさん
04/08/22 17:48
どういう型になるんだ?

175:デフォルトの名無しさん
04/08/22 17:53
map sum $ transpose [[1,2,3],[4,5,6],[7,8,9]] => [12,15,18]

こんなもんでどうでしょうか。

176:デフォルトの名無しさん
04/08/22 20:04
>>174
[a->b]->[a]->[b]かな?


177:デフォルトの名無しさん
04/08/22 20:10
zipWith ($)

178:デフォルトの名無しさん
04/08/22 20:54
Prelude> (zipWith ($)) (map (+) [1,2,3]) [4,5,6]
[5,7,9]

ナルホド。


179:デフォルトの名無しさん
04/08/23 11:43
只の関数適用(f x)と(f $ x)って何か違うところあるの?
それとも( )じゃワケがわからないから($)と書けるように
目に見える演算子として用意されているだけ?


180:デフォルトの名無しさん
04/08/23 12:19
$ は関数合成では?

181:145
04/08/23 12:35
関数合成は . でしょ。
>>179 何も代わらない。関数適用のための演算子だから。
本来の利用法は >>178 みたいなものなのかな(個々の要素にそれぞれ適用する
ためには、関数適用の演算子があると便利)。

f $ g x と書くと、演算子の優先度の関係上 f(g x) と同じことになるので便
利、ついでに結合性の関係で f $ g $ h x とか書ける、というのが個人的に
は嬉しい。カッコの省略にも使える。
関数合成はあくまで関数の合成の演算子なので、 f . g . h x とは書けない。
(f . g . h) x なら書けるけど。

182:デフォルトの名無しさん
04/08/23 16:17
可変個数の zipWith については、

Functional Pearl "Do we need dependent types?"
Daniel Fridlender and Mia Indrika, 2000 J. Functional Programming,
vol. 10, July.

URLリンク(www.cs.chalmers.se)

に載っているので興味があるひとは読んでみるべし。


183:デフォルトの名無しさん
04/08/24 12:40
>>171-181
> 只の関数適用(f x)と(f $ x)って何か違うところあるの?

ある。$はただの関数だから、引数の型がそこで固定される。
f :: a -> (forall b. b -> b) -> a
f x g = g x

とすると、f 0 id はOKだが、f 0 $ id はだめ。
ST Monadなんかをつかっていると結構引っかかる。

184:デフォルトの名無しさん
04/08/24 14:37
-- zipWithN
infixl 2 <$>
infixl 1 <->
(<$>) = map
(<->) = zipWith ($)
-- 例
-- (\x y z -> x + y + z) <$> [3,4] <-> [5,6] <-> [7,8]

----------------------------
-- 可変引数 
ncat :: NCat b => b
ncat = ncat' id 
class NCat a where
  ncat' :: (String -> String) -> a
instance NCat String where
  ncat' f = f ""
instance NCat b => NCat (Char -> b) where
  ncat' f x = ncat' (f . (x:))

-- 例
-- ncat 'a' 'b' 'c'

# >>183の171は179の間違い。

185:デフォルトの名無しさん
04/08/24 14:38
>>184
型指定が要った。
ncat 'a' 'b' 'c' :: String

186:デフォルトの名無しさん
04/08/24 20:08
携帯から読むと AA 判定されててワラタ >>183-185

187:デフォルトの名無しさん
04/08/26 20:44
AA的プログラミング

188:デフォルトの名無しさん
04/08/26 20:54
(--#) とか (*^-^*) とか?

189:デフォルトの名無しさん
04/08/30 23:20
Categories for the Working Mathematician の訳書ってなんていうタイトルでつか?

190:デフォルトの名無しさん
04/08/30 23:27
スマソ。
「そのうち出る」 = 「そのうち出版される」という意味か。
「テキストの候補に挙がる」ではなく。

191:デフォルトの名無しさん
04/08/31 00:44
誤爆にも程があります

192:デフォルトの名無しさん
04/08/31 12:01
「数学に勤しむ貴方のための圏論」てのがそれらしいが
近刊とあってまだ出てないようだ。

URLリンク(www.kyoto-su.ac.jp)

193:デフォルトの名無しさん
04/09/07 17:30
末尾再起すると、遅延評価されないですね。
(length (hoge xx yy zz)) < 3
とかで困る。かも。

194:デフォルトの名無しさん
04/09/07 20:50
>>193
> 末尾再起すると、遅延評価されないですね。
そんなことはない。

> (length (hoge xx yy zz)) < 3
> とかで困る。かも。
lengthがstrictだからhogeがlazyでも意味がないとはいえるが、
末尾再帰とは無関係なので、意味がわからない。

なにを誤解してるのですか?

195:デフォルトの名無しさん
04/09/08 10:49
>>193
『末尾再帰の最適化』をすると遅延評価できない(或いはその逆)、のことを言いたいのかな。
それだったら解る。

あ、でも例 (length (hoge xx yy zz)) < 3 の意味はやっぱりわからない。

196:デフォルトの名無しさん
04/09/08 18:24
>>195
> 『末尾再帰の最適化』をすると遅延評価できない(或いはその逆)、のことを言いたいのかな。
詳しく説明きぼんぬ。
gotoでジャンプするコードにするとサンクが作れないのかな?

197:デフォルトの名無しさん
04/09/09 23:56
>>195

take n 末尾再帰関数(無限リスト)

みたいなのが出来ないということでは?

198:197
04/09/10 00:26
括弧の位置を間違えた。
take n (末尾再帰関数 無限リスト ・・)
です。

199:193(初心者)
04/09/10 16:18:42
すいません。どっかいってました。
>197さんの言うとおりです。
例は適当にかいたらだめでした。

200:デフォルトの名無しさん
04/09/10 16:25:19
>>197-198
なにができないと?
take' 0 xs = xs
take' n (x:xs) = take' (n - 1) xs 

take n (take' 10 [0..])

201:197
04/09/10 21:59:52
>>200
返値も無限リストの場合です。

nub0 :: Eq a => [a] -> [a]
nub0 = nub0' []
nub0' l [] = l
nub0' l (x:xs)
  | elem x l = nub0' l xs
  | otherwise = nub0' (x:l) xs

take 10 (nub0 [1..])

202:デフォルトの名無しさん
04/09/10 22:16:02
>>201
nub0 [1..]自体がbottom(無限リストではない)なんだから
末尾再帰も糞もないですよ。

nub0' :: [Int] -> Int
nub0' = foldr (+) 0
だって同じこと。

203:197
04/09/10 23:25:33
いろいろと書き方がまずくてすみません。

nub0 を末尾再帰で定義したから、nub0 [1..] が
bottomになったわけで、Hugsでの定義の

nub l = nub' l [] where
 nub' [] _ = []
 nub' (x:xs) ls
  | x `elem` ls = nub' xs ls
  | otherwise = x : nub' xs (x:ls)

のようにすれば nub [1..] は無限リストになる、という意味です。

204:デフォルトの名無しさん
04/10/07 21:01:01
いいかげん誰かモナドをわかりやすく説明してくんない?
関数型言語のキモは副作用とのコラボレーションなんだし

205:デフォルトの名無しさん
04/10/08 02:06:46
>>204
URLリンク(www.sampou.org)
ではだめ?

206:デフォルトの名無しさん
04/10/14 01:54:56
んじゃ自分の理解度の確認を兼ねて。(突っ込みよろしく)

モナドは数学上はモノイドといって単位元を持つ半群のこと。
一応簡単な説明。
(X * X ) * X = X * ( X * X ) といった「結合側」が成り立つ演算*があって
(E * X ) = ( X * E ) = X となる単位元Eを持つようなXのこと。

X が整数だとすれば * は足し算 E は 0
もちろん * を掛け算 E は 1としてもいい。
* を文字列の結合 , Eを空文字列 "" とすれば文字列もモノイドとみなせる。

で、HaskellのIO型には
上の文字列モナド(モノイド)の1文字づつの代わりにOSのシステムコール呼び出しの機械語が
入っていると思えばいい。

IOモナドA( [キー入力] ) >> IOモナドB( [画面出力] )  を適用すると 
  IOモナドC( [キー入力]の次に[画面出力] ) になる

みたいな。
で どんどん >> や >>=で繋いでいくわけ。

もちろん結合則も成り立つ。
ちなみにreturn 関数が返すIO型が単位元になってる。

これはreturnの返すIOには何もシステムコール?が含まれてないから
上の文字列モナドの空文字列みたいな感じ

これで宜しいでしょうか>>204

207:デフォルトの名無しさん
04/10/14 03:55:12
>>206
Monoidだと思って話すなら:

結合法則: (a * b) * c = a * (b * c) を満たす演算*が定義されていて、
単位元 e (e * a = a * e = a をみたす) を持つような集合を
Monoid(以下、単に半群という)といいます。
例えば"行列"や"微分方程式の解作用素"は半群になっています。

*** Point(1): a * b /= b * a。順序は変えられない

この半群の集合への作用(注1)の仕方を定めたものがMonadです。
return == e で、あとは * にあたるものが >>= となります。
そういうと、return :: a -> M a (M "a" なのは単位元だから) なんだから、
>>= :: (s -> M t) -> (t -> M u) -> (s -> M u) 
じゃないのかと思うかも知れませんが、
>>= :: M t -> (t -> M u) -> M u
でもいいのです。
というのは、(c * d)' x = c' (d' x)なので、*を決めることと、
M sの任意の元(d' x 等)をどこにうつすかを決めることは同じことだからです。

続く。

208:207
04/10/14 03:57:32
この行は前のメッセージの最後にあるべきでしたが、

*** Point(2): x /= y ならば a' x と a' y は等しくなくてもよい


さて、例えばIOモナドなら、putStr :: String -> IO () 
は上のaやらbやらにあたります。ではgetLine :: IO Stringはというと、
元を一つしか持たない集合をUとしてgetLine :: U -> IO String の省略記法
なのです。元が一つしかないのだから、わざわざU->を考える必要はありません。

Point(1)、(2)がIOの、順序を変えられない、毎回違う答えが帰るかもしれない
という性質を満足させてくれます。

main = getLine >>= putStr は、(putStr * getLine) と同じもので、
実行するのは putStr' (getLine' world) を計算することです。
getLineが毎回異なる文字列をputStrに>>=で与えても、それはworld
が違ったからだと思えばなにも問題はありません。

*1 (作用)
    行列をベクトルにかけるとベクトルができますが、これと同じように、
    半群(M)の元(a, b, ..)をある集合(S)の上の関数とみなすことができます。
    好き勝手に関数とみなすのではなく、次の性質をみたすとき、
    半群MがSに作用している、ということにします。関数とみなすときには'をつけます。
    (a * b)' x = a' (b' x) (x は S の元)
    
# monoidとmonad (triple)はどちらも数学の概念で、似ていますが別物です。

209:デフォルトの名無しさん
04/10/14 08:51:55
(X * X ) * X = X * ( X * X ) といった「結合側」が成り立つ
の()の意味はなんだ?
単に型が合うかどうかか?演算の時間的な順番か?

210:デフォルトの名無しさん
04/10/14 09:25:14
>>209
演算の順序。
代数の本を読めばどしょっぱなに書いてあるよ。

211:デフォルトの名無しさん
04/10/14 09:29:17
じゃあ(入力 * 出力)* 入力 = 入力 * (出力 * 入力)になって
最初に出力してくれるのかい?

212:デフォルトの名無しさん
04/10/14 11:05:33
コードの結合順序と、実行順序を混同するな。

Cで {{f(); g();} h();} と {f(); {g(); h();}} が同じ結果になる
みたいなものだ。

213:デフォルトの名無しさん
04/10/14 15:33:35
だから(X * X ) * X = X * ( X * X )ってのはどういう意味なの?

214:デフォルトの名無しさん
04/10/14 16:42:30
>>213
モノイドの説明だとしたら、その式はそうとしか言えないのでは。整数上の加
算について考えると、
(1+2)+3 = 1+(2+3)
が結合則。
1+0 = 0+1 = 1
が単位元の性質ということ。数学の話だよ。

モナドだとすれば、 >>207-208 じゃないのか。
(f * (g * h)) x = ((f * g) * h) x = f(g(h(x)))
という風に理解したんだがこれは当ってる?

Haskell の記法を使えば、
x >>= (\x -> x >>= h >>= g) >>= f = x >>= h >>= (\x -> x >>= g >>= f)
かな?

モナドというのは、「評価の順序を保証するもの」という風に考えているんだ
が、その事を「結合則は成立するが、交換則は成立していない」という事で表
現しているということなのでは。

副作用の話は 208 の方に書いてあると思うんだが、こっちはよくわからない……。


215:デフォルトの名無しさん
04/10/14 17:00:35
>>214
> 「結合則は成立するが、交換則は成立していない」
「交換則は必ずしも成立するわけではない」のほうが適当では?

216:デフォルトの名無しさん
04/10/14 17:05:38
この場合の(X * X ) * X = X * ( X * X )の意味は
どういう風に括弧をつけても関数Xの適用順序は
左から右、右から左と一定であるって意味でいいの?

217:デフォルトの名無しさん
04/10/14 17:17:39
>>215
ああその通りですね。失礼しました。

>>213=216
まあその通りといえばその通りではないかと思います。
*を関数の合成みたいな演算だと考えればよいのでは。


218:デフォルトの名無しさん
04/10/14 17:22:34
で、208に質問なんですが、

> *** Point(2): x /= y ならば a' x と a' y は等しくなくてもよい

はわかるとして、 GetLine :: U -> IO String であり、 U が一点集合なのだ
としたら、これは x = y である(にもかかわらず a' x /= a' y になりうる)
例のように読めてしまったのですが、どこで間違えているんでしょうか?

getLine' world というのは、常に world が与えられるが、 world が毎回異
なるので返り値が異なることがあるっていうこと? でもそれって一点集合な
んでしょうか?

219:デフォルトの名無しさん
04/10/14 17:26:23
結合法則は分かったが

*** Point(1): a * b /= b * a。順序は変えられない
*** Point(2): x /= y ならば a' x と a' y は等しくなくてもよい
Point(1)、(2)がIOの、順序を変えられない、毎回違う答えが帰るかもしれない
という性質を満足させてくれます。

っていうのは普通の関数とどこが違うの?
普通の関数でもそういうのあるんだから、
モナドとかいわずに普通の関数と一緒に扱えばいいじゃない。

220:デフォルトの名無しさん
04/10/14 17:33:16
x = yでもa' x と a' yは等しくなくてもいいんじゃない?

221:デフォルトの名無しさん
04/10/14 17:50:24
結合法則は満たすけど交換法則は満たさないって状況、
小学校でやる一般的な算数にある?

222:デフォルトの名無しさん
04/10/14 17:52:51
引き算、割り算

223:デフォルトの名無しさん
04/10/14 18:00:53
結合法則満たすのか?

224:デフォルトの名無しさん
04/10/14 18:01:04
perl -e '$op="-"; print eval "4 $op (3 $op 2)"'
perl -e '$op="-"; print eval "(4 $op 3) $op 2"'
これ、答えが違っちゃうけど、、なんか間違ってます?

225:デフォルトの名無しさん
04/10/14 18:16:35
>>219
> っていうのは普通の関数とどこが違うの?
> 普通の関数でもそういうのあるんだから、

どこの世界の関数だそれは(w


226:デフォルトの名無しさん
04/10/14 18:23:24
べき乗とかなら交換したら意味がちがうし
x /= y ならば a' x と a' y は等しくないんちゃう?

227:デフォルトの名無しさん
04/10/14 18:27:33
もちつけ。モノイドがモナドなわけじゃないぞ。
> この半群の集合への作用(注1)の仕方を定めたものがMonadです。

228:デフォルトの名無しさん
04/10/14 18:29:58
>>219
逆で、関数でそういう性質が成り立って、文字列の連結や状態遷移でもそういう性質が成り立つからそれらを抽象化してモナドにしたってこと。
連結リストや配列リストの性質を抽象化してリストとして扱うようなのと同じ。

229:デフォルトの名無しさん
04/10/14 18:31:50
じゃあ普通の関数もモナド?

230:デフォルトの名無しさん
04/10/14 18:42:39
>>220
x = y で a' x = a' y でなくても構わないっていうのは数学的にはおかしい
気がしますが。
プログラム的には副作用が起きているなら成立すると思いますが、その副作用
を上手く扱うのがモナドなんじゃないの?

231:デフォルトの名無しさん
04/10/14 18:54:09
順序は正しく守って、毎回違った答えが出ても
処理系はエラーを出さず理論的にもきちんとまとめられるってことか?

232:207
04/10/14 19:02:54
>>218
そうですね。すみません。208は全然ダメです。 
モナドをモノイドで押し切ろうというのは無理がありました。

233:デフォルトの名無しさん
04/10/14 19:03:15
>>229
普通の関数だと、たとえば
f(g(x), h(y))
がどの順番で評価されるかは不定。でも、モナドを使えば、その順序を確定さ
せることができる。

……副作用とかいう話じゃなくて、順序を確定させることが重要なのかなあ。
順序が確定的だから、副作用が起きるコードでもOKみたいな感じ?

234:デフォルトの名無しさん
04/10/14 19:06:11
モナドってのは何をさすんだい?
a * bだったらaやbがモナド?それとも*がモナド?

235:207
04/10/14 19:15:28
>>233
順序と、引数返り値に直接アクセスできないところが味噌です。
type IO a = world -> (a, world)
なら、main world0 = let (s, world1) = getStr world0 in print s world0
とかやってしまえないようになるところ。

>>234
a, bと*の組みです。
行列群が、行列と行列のかけ算の両方がないと考えられないのと同様に。

236:デフォルトの名無しさん
04/10/14 19:18:35
a,bはプログラム中の式
*は各式の関係を表す演算子

237:207
04/10/14 19:27:09
>>232 自己レスもちろん>>207もだめです。
モナドは雰囲気はモノイドなんですがやっぱりモノイドとは
みなせそうにないので、これも嘘です。
> この半群の集合への作用(注1)の仕方を定めたものがMonadです。
予想と違って、正しいかもしれないものだと素直に読んだ方が
多かったようで、申し訳ないです。

238:デフォルトの名無しさん
04/10/14 19:31:13
理解した部分だけ書くと、結合法則を満たす関数の合成を使うと
IOのような実行の順序が重要な意味をもつ関数を(順序不定で)合成しても
合成された関数は一意的な順序でIOが実行される関数になるということか?

順序を保つ合成が結合法則を満たすのは分かったが、
結合法則を満たす合成は全て実行の順序を保つでいいのか?

239:デフォルトの名無しさん
04/10/14 21:14:39
>>238
順序不定には合成できないから、明示的に順序をつけることを強制できる。

putStr (getLine, [getChar])
でなく
getLine >>= (\s -> getChar >>= (\c -> putStr (s, [c])))

getChar >>= (\c -> getLine >>= (\s -> putStr (s, [c])))

240:デフォルトの名無しさん
04/10/14 21:26:54
じゃあモナドは実行の順序が決められてる関数の中の一つってことか?

241:デフォルトの名無しさん
04/10/14 21:57:19
例えば左から右へ順番に実行する関数hogeが定義できて、
hoge getLine getCharから
getLine >>= (\s -> getChar >>= (\c -> putStr (s, [c])))と
同じ動作を定義できるのか?

242:デフォルトの名無しさん
04/10/15 01:54:14
>結合法則を満たす合成は全て実行の順序を保つでいいのか?

これは成り立たないと思う。

モナドの結合法則の概念と順序は本来関係ないんじゃないかな。
たまたま順序を組み立てるのにモナドが使えるってだけだと思う。

URLリンク(www.sampou.org)
↑のListモナドとかは
順序とは関係なさそうだし。(関数から複数の遅延込みの非正格値を返すためのもの?)
モナドの用途は順序の決定のみにあらずってとこか。

243:デフォルトの名無しさん
04/10/15 04:12:02
>>241
hoge :: IO String -> IO Char -> IO ()
hoge f g = f >>= \s -> g >>= \c -> putStr (s, [c])

getLine :: String、getChar :: Char だったら無理。

244:デフォルトの名無しさん
04/10/15 04:13:08
>>242
> List モナドは非決定性をもつ計算の連鎖を、演算をそれぞれのステップで可能なすべての値に適用することで、合成する戦略を内包しています。
だけなら、モナドでなくてもいいね。
------------
module MList where

data MList a = a :*: (MList a) | MNull deriving (Eq, Show)
infixr 3 :*:


instance {- Broken -} Monad MList where
  (x :*: xs) >>= f = merge (f x) (xs >>= f)
    where 
      merge (x :*: xs) ys = x :*: merge ys xs
      merge MNull ys = ys
  MNull >>= f = MNull
  return x = x :*: MNull
  fail s = MNull

toMList xs = foldr (:*:) MNull xs

(>=>) = (>>=) -- 2ch : ">> が多すぎます!"
(>=>) :: Monad m => m a -> (a -> m b) -> m b
test f = test1 f == test2 f
test1 f = f [1,2] >=> \x -> f [3, 4] >=> \y -> f [5, 6]
test2 f = (f [1,2] >=> \x -> f [3, 4]) >=> \y -> f [5, 6]

245:デフォルトの名無しさん
04/10/15 08:50:04
そうだよなあ。
モナドが「暗黙の引数world」と「関数のeagerな評価」を意味するだけなら,結合法則はなくてもよい。

246:デフォルトの名無しさん
04/10/15 11:05:46
IOモナドについて。
話の流れから多少それるのかもしれませんが、
IOモナドの僕のとらえかたは以下のような感じです。

putStrはStringを引数としてとり、
「その文字列を表示する動作」を返す関数。
であり、putStr "Hello " >> putStr "World"
とした場合、putStr "Hello "とputStr "World"のそれぞれが評価される
順番は問題ではない。
putStr "Hello "が評価された時点では、
"Hello "は出力されずに、「"Hello "を出力する動作」が
決定するだけである。
そして、putStr "Hello " >> putStr "World"は、
"Hello "を出力した後に"World"を出力する動作として評価される。
この時点では何の出力も生じない。
この動作は、main = ...というように、mainに代入されることにより、
評価器とは切り離された装置によって出力に変えられる。

つまり、putStr "Hello " >> (putStr "World" >> putStr "\n")
とした場合、putStr "World >> putStr "\n"の部分が先に評価されて、
「"World"を出力した後に、"\n"を出力する動作」となり、
その後に、putStr "Hello "と結び付けられて、
「"Hello "を出力した後に「"World"を出力した後に"\n"を出力」する動作」
となる。
これは、
「「"Hello "を出力した後に"World"を出力」した後に"\n"を出力する動作」
と等しい。

247:デフォルトの名無しさん
04/10/15 12:01:44
>>246
ありがとう、やっとすっきりした。
つまり継続を渡しているわけね。


248:デフォルトの名無しさん
04/10/15 12:14:00
>>246
> であり、putStr "Hello " >> putStr "World"
> とした場合、putStr "Hello "とputStr "World"のそれぞれが評価される
> 順番は問題ではない。

順番は問題。これは左から評価しないと(されるように>>が定義されてないと)、
putStr "Hello ">> error "Error." 等が正しくうごかない。

> この動作は、main = ...というように、mainに代入されることにより、
> 評価器とは切り離された装置によって出力に変えられる。

上とも関連して、出力しながら内部の式を評価するわけで、
評価し終わったものを実行するのでは「ない」のだから、
 main world を評価すると考えるほうがいいのでは。

上で自分でもただStateモナドのようにかいてしまったけれど、
IO a = World -> (a, World) {- ただしStrict -} と思うことにして。 

(正則性と関連して実はIOはモナドの結合法則を満たしていなかったような)


> つまり、putStr "Hello " >> (putStr "World" >> putStr "\n")
> とした場合、putStr "World >> putStr "\n"の部分が先に評価されて、

ここも左から評価される。

あとは大体OKと思う。

249:デフォルトの名無しさん
04/10/15 17:24:40
>>248
>順番は問題。
>>256
> putStrはStringを引数としてとり、
>「その文字列を表示する動作」を返す関数。
という前提だからいいんじゃないの?


250:デフォルトの名無しさん
04/10/15 18:08:50
>>249
putStr "Hello " >> error "Error." 
の右辺を先に評価したら"Hello"が表示される前にerrorで終わってしまうでしょ。

正格性解析かなにかで>>の左辺と右辺が
Strictにしかも_|_にならずに評価できると知っていたら
何かの気まぐれで右辺から評価するかもしれないけど、基本は左から。

ちなみに右から(Lazyに)評価したら末尾再帰も無意味になるし無限ループも書けない。

251:デフォルトの名無しさん
04/10/15 20:36:06
ちなみに右から(Lazyに)評価したら末尾再帰も無意味になるし無限ループも書けない。
どういう意味だ?


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5378日前に更新/259 KB
担当:undef