関数型プログラミング言語Haskell Part9
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさん
2008/05/17(土) 16:41:29http://www.haskell.org/
日本語サイト
http://www.sampou.org/cgi-bin/haskell.cgi
http://www.shido.info/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/
Part6 http://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 http://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 http://pc11.2ch.net/test/read.cgi/tech/1193743693/
・2chの仕様により、行頭の半角スペースは表示されません。
コードをインデントしたいときは、代わりに または全角スペースを使うことができます。
0830デフォルトの名無しさん
2008/10/09(木) 20:20:13Prelude関数ではないのでData.Listをインポートしないと使えない。
>>829
だったら >>825 が最初に言ってる変更をするか、rot90を使わずにtransposeを定義すれば。
0831デフォルトの名無しさん
2008/10/09(木) 21:12:45transpose :: [[a]] -> [[a]]
transpose [] = []
transpose ([] : xss) = transpose xss
transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) : transpose (xs : [ t | (h:t) <- xss])
0832デフォルトの名無しさん
2008/10/10(金) 06:57:02連続した半角スペースはjavascriptモードで書き込むときに置換されるらしい。
>>824-825
長方形じゃないときに、all だとエラー、any だと長方形になるように切り落とす。
filter 使えば>>831の transpose に map reverse . したような感じになる。
([<h or t> | h:t<-xss] = map <head or tail> (filter (not.null) xss))
違ったやり方なら
rot90 = foldl c []
where
c yss [] = yss
c [] xs = [[x] | x<-xs]
c (ys:yss) (x:xs) = (x:ys) : c yss xs
とか。
0833デフォルトの名無しさん
2008/10/10(金) 07:01:540834デフォルトの名無しさん
2008/10/11(土) 00:49:41パッケージの管理方法にいろいろと問題がある。
0835デフォルトの名無しさん
2008/10/11(土) 01:26:24具体的に言ってくれよ。そして開発者達にも。
0836デフォルトの名無しさん
2008/10/27(月) 20:53:56るのですが、遅延評価が効くようなコードが書けません。
type FileTree = Tree FilePathとして、以下のような関数を作ってみたのですが。
recursiveFileTree :: FilePath -> IO FileTree
recursiveFileTree name = do
contents <- catch (getDirectoryContents name) (\e -> return [])
children <- let
filtered = filter filterDots contents
pathadd = map (\x -> name </> x) filtered
mapped = map recursiveFileTree pathadd
in sequence mapped
return (Node (takeFileName name) children)
where filterDots :: FilePath -> Bool
filterDots "." = False
filterDots ".." =
filterDots _ = True
(インデントしてるように見せるために全角スペースを入れています。見えますか?)
おそらくsequenceで[IO FileTree] -> IO [FileTree]としているあたりが問題なのだと思いますが、解決策が分かりません。
0837デフォルトの名無しさん
2008/10/27(月) 22:14:59・Data.Treeを使うのをやめて、明示的なIOを伴う木を定義して使う
好きな方を選んでくれ
0838デフォルトの名無しさん
2008/10/27(月) 22:22:13IOは実行順が重要なことが多く、遅延させて順番をうやむやにすると厄介なことになりやすい
それだとどうしても不便というときのためにunsafeInterleaveIOがある
0839デフォルトの名無しさん
2008/10/30(木) 10:12:080840デフォルトの名無しさん
2008/10/30(木) 11:26:170841デフォルトの名無しさん
2008/10/30(木) 17:56:420842デフォルトの名無しさん
2008/10/30(木) 18:02:48flip (flip f b) c → 17文字
0843デフォルトの名無しさん
2008/10/30(木) 19:39:380844デフォルトの名無しさん
2008/10/30(木) 19:45:59(flip.(flip f)) b c
3引数flip
http://haskell.g.hatena.ne.jp/mr_konn/20061223/1166869265
0845デフォルトの名無しさん
2008/10/30(木) 19:54:21あと、内側の括弧は無くてもOK
0846デフォルトの名無しさん
2008/10/30(木) 21:45:300847デフォルトの名無しさん
2008/10/30(木) 23:03:150848デフォルトの名無しさん
2008/10/30(木) 23:47:190849デフォルトの名無しさん
2008/10/31(金) 08:29:54>>839
0850デフォルトの名無しさん
2008/10/31(金) 11:19:22それだと
f # b c -- \a -> f a b cと同等
と
(f #) b c -- (\a -> f a) b cと同等
を区別する必要が出てきて面倒だな
0851デフォルトの名無しさん
2008/11/02(日) 13:03:16ブログ持ってないのでここで。酒井さんのパクリ。
{-# OPTIONS -fglasgow-exts #-}
import Control.Monad (liftM2)
import Data.Either
import Test.QuickCheck
infix 4 :<->:
type a :<->: b = (a -> b, b -> a)
(.>) :: a:<->:b -> b:<->:c -> a:<->:c
(f1,g1) .> (f2,g2) = (f2 . f1, g1 . g2)
un :: a:<->:b -> b:<->:a
un (f,g) = (g,f)
type a :+: b = Either a b
infixr 5 :+:
alt :: a:+:b :<->: b:+:a
alt = (f,f) where f = either Right Left
swap :: a:+:b:+:c :<->: b:+:a:+:c
swap = (f,f) where f = either (Right . Left) (either Left (Right . Right))
rt :: b :<->: c -> a:+:b :<->: a:+:c
rt (f,g) = (r f, r g) where r = either Left . (Right .)
0852デフォルトの名無しさん
2008/11/02(日) 13:04:16fold :: a:+:(T,(T,a)) :<->: (T,a)
fold = (f,g)
where
f (Left a) = (L,a)
f (Right (t1,(t2,a))) = (N t1 t2,a)
g (L,a) = Left a
g (N t1 t2,a) = Right (t1,(t2,a))
h :: (T,a) :<->: a:+:(T,a):+:(T,(T,(T,a)))
h = un fold .> rt (un fold)
s :: a:+:(T,(T,(T,a))) :<->: (T,a):+:(T,(T,(T,(T,a))))
s = rt (un fold .> alt) .> swap .> rt fold .> alt
0853デフォルトの名無しさん
2008/11/02(日) 13:05:44st =
-- T
h
-- 1 + T + T^3
.> swap
-- T + 1 + T^3
.> rt (s .> s .> s .> s
-- T + T^4 + T^7
.> alt)
-- T + T^7 + T^4
.> swap
-- T^7 + T + T^4
.> rt (s .> s .> s .> s .> s)
-- T^7 + T^6 + T^9
.> swap
-- T^6 + T^7 + T^9
.> un h
-- T^7
0854デフォルトの名無しさん
2008/11/02(日) 13:08:02arbitrary = oneof [return L, liftM2 N arbitrary arbitrary]
main :: IO ()
main = do
quickCheck $ \x -> x == (snd st (fst st x) :: (T,()))
quickCheck $ \x -> x == fst st (snd st x :: (T,()))
型検査で漏れてるのは fold の定義ぐらいで、QuickCheck 意味ないのかも。
0855デフォルトの名無しさん
2008/11/03(月) 11:50:000856デフォルトの名無しさん
2008/11/05(水) 07:40:020857デフォルトの名無しさん
2008/11/05(水) 08:34:43みたいなテクニックが沢山載ってるようなページを教えてください
0858デフォルトの名無しさん
2008/11/05(水) 12:06:08unsafeInterleaveIO (IO m)
= IO ( \ s -> let
r = case m s of (# _, res #) -> res
in
(# s, r #))
この#って何なんですか?ghc6.8.2ではエラーになりますし…
0859デフォルトの名無しさん
2008/11/05(水) 12:38:02unboxed tupleってやつだね。
http://itpro.nikkeibp.co.jp/article/COLUMN/20070206/260872/?ST=develop&P=2
>>856
Windows版を入れてみたんだけど、ライブラリの置き場所がキモイな。
6.8だと$topdir/lib以下に入ってたのが6.10.1だと$topdirに入ってる。
キモイし$topdirの見通しも悪いので6.8と同じように$topdir/libの中に移動して
package.confの中の$topdir\\を$topdir/lib\\に全置換した。
0860デフォルトの名無しさん
2008/11/05(水) 14:29:51ありがとうございました
拡張構文なんですね
0861デフォルトの名無しさん
2008/11/06(木) 23:45:000862デフォルトの名無しさん
2008/11/08(土) 00:10:49Haskellの処理系だけを使って、prologみたいなことができないか調べています。
↓でprologのタプル parent(tom, bob). のような感じにすると、
parent::[Char]->[Char]->Bool
parent "tom" "bob" = True
parent "liz" "bob" = True
parent "mike" "liz" = True
parent _ _ = False
とりあえず、
main = print $ parent "tom" "bob"
main = print $ parent "mike" "bob"
で True や False が出て、prologっぽくなります。
そこで、
parent X "bob"
という質問に対し、
X=tom
X=liz
みたいに変数にユニファイするような定数を手に入れるような仕組みってあるでしょうか?
入門書に、コンパイル時に内部でグラフを作るみたいな話が書いてあったので、
そのグラフを参照できるようなことができれば実現できると思うのですが、無理でしょうか?
0863デフォルトの名無しさん
2008/11/08(土) 00:23:23無理
Haskellの関数は文字通り関数なので、引数を放り込んで結果を観察する他に使い道は無い
0864デフォルトの名無しさん
2008/11/08(土) 00:43:200865デフォルトの名無しさん
2008/11/08(土) 01:15:29グラフ簡約のことを言ってるのなら、グラフが作られるのは実行時だし、
要するに「未評価の式」を表してるだけだから、それを見ても>>862みたいなことをする助けにはならんよ
0866デフォルトの名無しさん
2008/11/08(土) 01:27:35Haskellって厳格な言語で、その手の変なことは基本的にできないよ。
何をやりたいのか知らないけど、インタプリタ的なものを書いて、
それをライブラリとして使えば?
0867デフォルトの名無しさん
2008/11/08(土) 01:38:050868デフォルトの名無しさん
2008/11/08(土) 02:16:43先にグラフを作って、実行時に、そこにデータを流し込むような感じの説明があったから、
処理系をそのまま利用して、かなり高速なデータベースが作れると思ったんですけどダメですかね。
実現できればprologよりも表現能力が高いから面白そうだと思ったんですが。
0869デフォルトの名無しさん
2008/11/08(土) 03:27:38これはその通り
>先にグラフを作って、実行時に、そこにデータを流し込む
これはぜんぜん違う
多分どこかで誤読してると思う
0870デフォルトの名無しさん
2008/11/08(土) 11:40:05zs <- everything
append [1..100] [1..100] zs
こういうやり方じゃ生きてるうちに終わらないかもよ。
Listモナドは、もちろんユニフィケーションや制約伝播なんて無くて、
総当りで解を求めようとする非決定性計算ってだけなんで。
0871デフォルトの名無しさん
2008/11/08(土) 11:50:02http://okmij.org/ftp/Prolog/Arithm/DefinitionTree.hs
いまいち使い方はわからんけど、ググったら見つかったので貼っておく。
0872デフォルトの名無しさん
2008/11/08(土) 20:48:35failや[]で枝狩り
0873デフォルトの名無しさん
2008/11/09(日) 00:44:22変数をどう表現して、何をどう枝刈るの?
0874デフォルトの名無しさん
2008/11/22(土) 08:25:24Real World Haskellは糞本だと思う
0875デフォルトの名無しさん
2008/11/23(日) 12:49:160876デフォルトの名無しさん
2008/11/25(火) 23:01:38ttp://d.hatena.ne.jp/mokehehe/20081124/rwh
0877デフォルトの名無しさん
2008/11/25(火) 23:27:230878デフォルトの名無しさん
2008/11/25(火) 23:41:58マイナーな言語だけど、微妙にブームになってるし
来年ぐらいに出版されたりするかなあ?
0879デフォルトの名無しさん
2008/11/25(火) 23:48:260880a36 ◆K0BqlCB3.k
2008/11/25(火) 23:50:52最近は沈静化したように見せかけて、ジワジワきてるよ。
各大学の卒研レベルではHaskellやったりしてるところが増えてきてる。
0881デフォルトの名無しさん
2008/11/26(水) 00:04:130882a36 ◆K0BqlCB3.k
2008/11/26(水) 00:08:270883デフォルトの名無しさん
2008/11/26(水) 00:12:16ふつケルの次くらいに読む分には悪くないと思う>RWH
タダだし
0884デフォルトの名無しさん
2008/11/26(水) 00:17:39翻訳本が出るまでそれですまそうかなw
0885デフォルトの名無しさん
2008/11/26(水) 00:19:3411章からはページを増やすためにネタを書きましたって
レベルのオナねたのオンパレードだぞ
0886デフォルトの名無しさん
2008/11/26(水) 00:36:340887デフォルトの名無しさん
2008/11/26(水) 00:45:560888デフォルトの名無しさん
2008/11/26(水) 00:49:090889デフォルトの名無しさん
2008/11/26(水) 01:23:560890デフォルトの名無しさん
2008/11/26(水) 01:48:330891デフォルトの名無しさん
2008/11/26(水) 07:48:38Cardelli読め
0892デフォルトの名無しさん
2008/11/26(水) 13:02:02と
Programming in Haskell
のどちらがお勧めですか?ふつけるの次くらい。
0893デフォルトの名無しさん
2008/11/26(水) 21:24:32下手糞な翻訳の恐れ大。最近多いね、いや昔からか
0894デフォルトの名無しさん
2008/11/26(水) 22:52:490895デフォルトの名無しさん
2008/11/27(木) 19:14:12自分はふつけるの後にCraftでした。というか、その間にSICPが
あるので、あんまり参考にならないかな。ふつける読んでも
ちょっとピンとこなかったんですね、よくまとまってるとは思うのですが。
自分は普通の文系プログラマで、関数型プログラミングの世界とは
無縁だったので、SICPをくぐる必要があったと感じてます。
0896デフォルトの名無しさん
2008/11/27(木) 19:30:500897デフォルトの名無しさん
2008/11/27(木) 19:55:34あとはReal Worldみたいな実用面を書いたものになりますかね。
0898デフォルトの名無しさん
2008/11/27(木) 20:02:060899デフォルトの名無しさん
2008/11/28(金) 20:17:320900デフォルトの名無しさん
2008/11/28(金) 22:32:120901デフォルトの名無しさん
2008/11/28(金) 23:59:300902デフォルトの名無しさん
2008/11/29(土) 00:04:26ってのをやってますが、練習問題の回答とかどっかに転がってますでしょうか。
0903デフォルトの名無しさん
2008/11/29(土) 11:25:49著者本人が公開してる。あとは自分で探せクズ。
0904デフォルトの名無しさん
2008/11/29(土) 11:27:36おめーがクズだろ
この引きこもりw
0905デフォルトの名無しさん
2008/11/29(土) 21:15:400906デフォルトの名無しさん
2008/11/29(土) 22:05:13maximaと比べると
言語から直接利用するときの利用しやすさは、どんな感じなのでしょうか?
0907デフォルトの名無しさん
2008/11/30(日) 09:20:370908902
2008/11/30(日) 09:56:28自分では探してみましたが、部分的なコードだけしか見つけられませんでした。
ちなみに、自分は学生ではないんです。輪読の場があったりしたら入りたい
ですけど、ちょっと今は時間的に厳しいかな。ネットでやってたりするといいん
ですが。
0909デフォルトの名無しさん
2008/11/30(日) 16:00:410910デフォルトの名無しさん
2008/11/30(日) 21:28:442021年4月19日に出るみたいです。
まだ相当先ですね。
0911デフォルトの名無しさん
2008/12/01(月) 20:25:35今度はありえないくらいに延ばしたな・・・
0912デフォルトの名無しさん
2008/12/07(日) 12:54:19Linux 上だとちゃんと動いて便利だったのでショックです。
ネット探してみると rlwrap 使えとかあったけど
rlwrap って動的な補完(スコープ内の関数一覧等)
って可能なんでしょうか。
0913デフォルトの名無しさん
2008/12/07(日) 13:54:210914デフォルトの名無しさん
2008/12/07(日) 13:56:280915902
2008/12/07(日) 20:05:48書いてありました。これって個人でも送ってくれるのでしょうかね。
ただ、まだ半分ぐらいなんですけど、問題簡単なので別に解答不要
になりそうです。ありがとうございました。
0916デフォルトの名無しさん
2008/12/13(土) 18:52:49do;putStr "a\n";putStr "b\n";putStr "c\n";
≡
putStr "a\n" >>= (\_->putStr "b\n" >>= (\_-> putStr "c\n"))
なんですかね?
右結合的になったり匿名関数に変換されたりと難しいです
0917a36 ◆K0BqlCB3.k
2008/12/13(土) 19:06:24一緒です。
でも
putStr "a\n">>putStr "b\n">>putStr "c\n"
と書いた方がきれいですよ。
0918a36 ◆K0BqlCB3.k
2008/12/13(土) 19:06:570919デフォルトの名無しさん
2008/12/14(日) 10:36:09ありがとうございました
0920デフォルトの名無しさん
2008/12/14(日) 15:42:38fold/undold、flip とかを使った関数合成がすげえ苦手なんですが
このあたりに特化した書籍とかってないでしょうか
モナドとか継続とかはわりとどうでもいいんですが
0921デフォルトの名無しさん
2008/12/14(日) 16:19:34birdがそういうの得意な人だから、
Introduction to Functional Programming using Haskell
http://www.amazon.com/Introduction-Functional-Programming-using-Haskell/dp/0134843460/
"Using Haskell"じゃない前の版の方がその辺は内容が濃かった。
The Algebra of Programming
http://www.amazon.com/Algebra-Programming-Prentice-Hall-International-Computer/dp/013507245X/
は関数合成、変形ドリルみたいな内容だった。
たしかparserを必要な機能を持つように変形する論文もあったはず。
0922デフォルトの名無しさん
2008/12/14(日) 17:06:400924デフォルトの名無しさん
2008/12/15(月) 17:13:13cfold' f z [] = z
cfold' f z (x:xs) = f x z (\y -> cfold' f y xs)
という継続fの与え方次第でfoldlにもfoldrにもなるものが出てきたんですが
普通のfoldlやfoldrの定義からこれを導きだす手順のようなものがあるなら知りたいです
また「なんでも再帰」流に一つ引数増やして、最後にそれを必ず呼び出すようにして
末尾再帰の形に直していく…ってやり方で書こうとしてますがさっぱりです
0925デフォルトの名無しさん
2008/12/16(火) 12:48:15fac 0 = 1
fac n = n * fac (n-1) なのか
fac n = fac (n-1) * n なのかってことだから、
fac n = ((n *) . fac) (n-1)あるいは、
fac n = ((* n) . fac) (n-1)
fac n = (((\m ->(m *)) n) . fac) (n-1)あるいは、
fac n = (((\m ->(* m)) n) . fac) (n-1)
fac0 f n = ((f n) . (fac0 f)) (n-1)で
fac0 (\m ->(m *)) nあるいはfac0 (\m ->(* m)) n
\m ->(m *)と\m ->(* m)は、
fac(n-1)を計算した後にすべき計算、つまり継続になっています。
0926デフォルトの名無しさん
2008/12/16(火) 12:51:01その累積演算を関数に独立させると、foldの性質上、継続的になるのです。
mapだとこうはなりません。
0927デフォルトの名無しさん
2008/12/16(火) 22:40:24ところがどっこい、この説明のすぐ後で、
「CPSを使ってmapとfilterを書け」なんて演習問題が出されてるわけですよ。
それを考えると、foldlの定義からcfold'へ持っていってあげたほうが
親切かもしれません。
0928デフォルトの名無しさん
2008/12/16(火) 22:53:36「yet another haskell tutorial の cfold' の説明」のことね。
0929デフォルトの名無しさん
2008/12/16(火) 23:38:03cfold'は、元のfold*の引数に渡す演算自体が継続的になるのに対して、
mapでは引数に渡す演算ではなくて、:が継続的になるわけです。
だからYAHTでは微妙に表現を変えています。
map f = foldr (\x -> ((f x) :)) []
ですから当たり前ですけども。
0930デフォルトの名無しさん
2008/12/19(金) 19:38:36すまん、「継続的」という言葉の意味がさっぱり分からん。
CPSにしたときに最後に行われる計算、という意味なら、
foldlは「foldl」自体が継続的、
foldrは引数として渡す関数「f」が継続的ということになるので、
fold*で継続的となる関数が同じになるとは思えない。
レス数が900を超えています。1000を超えると表示できなくなるよ。