関数型プログラミング言語Haskell Part5
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2006/06/03(土) 00:53:50http://www.haskell.org/
日本語サイト
http://www.sampou.org/cgi-bin/haskell.cgi
http://www.geocities.jp/shido_takafumi/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/
関連スレは>>2
関連書籍は>>3
0153デフォルトの名無しさん
2006/06/10(土) 20:11:500154デフォルトの名無しさん
2006/06/10(土) 21:01:160155デフォルトの名無しさん
2006/06/10(土) 21:06:130156デフォルトの名無しさん
2006/06/10(土) 22:10:28> ふつうのHaksell
それ、パチもんだから。
0157デフォルトの名無しさん
2006/06/11(日) 01:40:36無理だと思った人はとっととあきらめて。
0158デフォルトの名無しさん
2006/06/11(日) 02:20:20Haksellができたところで現実的には何も変わらんから気にするな
0159デフォルトの名無しさん
2006/06/11(日) 03:10:220160デフォルトの名無しさん
2006/06/11(日) 05:10:03物事を再帰関数で考える所も、ワーキングメモリ増強に良い気がします。
0161デフォルトの名無しさん
2006/06/11(日) 05:11:53コンキャット?
0162デフォルトの名無しさん
2006/06/11(日) 07:10:380163デフォルトの名無しさん
2006/06/11(日) 07:35:310164デフォルトの名無しさん
2006/06/11(日) 09:52:520165デフォルトの名無しさん
2006/06/11(日) 10:00:29再帰で考える方がワーキングメモリは少なくて済むんじゃないか。
0166デフォルトの名無しさん
2006/06/11(日) 10:16:56俺は最初再帰関数の処理手順がイメージつかなくて脳が悲鳴を上げた
脳にスタックを作るのはいい体操になると思う
0167デフォルトの名無しさん
2006/06/11(日) 11:28:030168デフォルトの名無しさん
2006/06/11(日) 11:31:110169デフォルトの名無しさん
2006/06/11(日) 11:32:350170デフォルトの名無しさん
2006/06/11(日) 11:56:230171デフォルトの名無しさん
2006/06/11(日) 12:03:310172デフォルトの名無しさん
2006/06/11(日) 12:04:150173デフォルトの名無しさん
2006/06/11(日) 12:11:550174デフォルトの名無しさん
2006/06/11(日) 12:30:150175デフォルトの名無しさん
2006/06/11(日) 13:33:320176デフォルトの名無しさん
2006/06/11(日) 13:35:110177デフォルトの名無しさん
2006/06/11(日) 15:10:26あれいじってなんか書け
0178デフォルトの名無しさん
2006/06/11(日) 15:18:14Pythonと比べて30倍くらい時間かかる。
0179デフォルトの名無しさん
2006/06/11(日) 15:26:54今のところはね。
0180デフォルトの名無しさん
2006/06/11(日) 16:05:170181デフォルトの名無しさん
2006/06/11(日) 16:47:36まあその代わり素晴らしい表現力があるが。
0182デフォルトの名無しさん
2006/06/11(日) 17:08:20unicode対応まだ〜?チンチン!!(AA略)
0183デフォルトの名無しさん
2006/06/11(日) 18:23:350184デフォルトの名無しさん
2006/06/11(日) 19:02:14# ["漢字文字列"] ;;
- : string list = ["\138ソ\142\154\149カ\142\154\151\241"]
↑これを使えるっていうのならね
0185デフォルトの名無しさん
2006/06/11(日) 19:46:20何の煽りか知らないけど、
代数学の知識なんて要らないんじゃ?集合論の知識すら要らないような。
モナドの話になるとちょっと代数が関わってくるけど,Haskellerならreturnが単位元な事と>>=の結合則が成り立つ事が分かっていればいい。
Haskell は
・マニュアルの読み方
・データと型の名前空間が違うということ
・構築子は大文字で,関数や型変数は小文字だということ
・演算子の中置記法
・let文の書き方
・パターンマッチの使い方
・型構築子の概念 (Either a bは a と b の 二つの「型引数」を持った型,とか)
・IOモナドの使い方 (>>=とreturnの型が分かること)
これだけわかればとりあえず使えるはず。(常識的なC,Javaに慣れていれば)
高階関数なんかは頭をひねってくれ。lisp/schemeでも使うでそ。
0186デフォルトの名無しさん
2006/06/11(日) 19:51:10(>>=) :: IO a -> (a -> IO b) -> IO b
を
(先にやるアクションA) >>= (Aの戻り値を受け取り,次にやるアクションBを返す関数)
== Aの次にBを行うアクション
という風に理解できればOK。
細かいサブルーチンを組み合わせて大きなサブルーチンをつくるのが >>=という演算子。
例えば
myprint str = putStrLn str
getLine >>= myprint
は, getLine >>= \str -> myprint str
と同じで,do構文なら,
do
str <- getLine
myprint str
ということ。ただこれだけ。
0187デフォルトの名無しさん
2006/06/11(日) 20:16:31> Haskellerならreturnが単位元な事と>>=の結合則が成り立つ事が分かっていればいい。
代数じゃん!
0188デフォルトの名無しさん
2006/06/11(日) 20:17:31wwwwwwwwwwwwwwwwwwww
0189デフォルトの名無しさん
2006/06/11(日) 21:02:09別に成り立たなくてもプログラムの意味は変わらないと思う
0190デフォルトの名無しさん
2006/06/11(日) 21:14:34do
a
b
c
と
do
a
do
b
c
で意味が違うのは嫌じゃないか?
0191デフォルトの名無しさん
2006/06/11(日) 22:06:19何わらってんだかしらんが、一文字を一文字として扱えない段階で話にもなってないって事じゃねぇの?
0192デフォルトの名無しさん
2006/06/12(月) 00:00:00それとも英語も出来ない人ですかw
0193デフォルトの名無しさん
2006/06/12(月) 00:12:45釣りですか?
0194デフォルトの名無しさん
2006/06/12(月) 01:05:17釣りですか?
0195デフォルトの名無しさん
2006/06/12(月) 01:11:51釣りですか?
0196デフォルトの名無しさん
2006/06/12(月) 01:22:59can
do
shityainayo
0197デフォルトの名無しさん
2006/06/12(月) 06:36:21なんと遅延評価させるものより遅くなった!
死にたい
0198デフォルトの名無しさん
2006/06/12(月) 06:41:55自分で一からモナドを書かない限り、代数は使わなくても済むよ〜、
と言いたかった。
もちろん知っておいた方がいいのは間違いない。
他にfoldrとfoldlは与える演算子が結合的なら結果が同じになるとか。
ただ普通にCやJavaでやっていた計算をHaskellでやる分には何も考えなくても書ける。
0199197
2006/06/12(月) 06:59:150200デフォルトの名無しさん
2006/06/12(月) 09:07:00そういう煽り方しておもしろいですか?
0201デフォルトの名無しさん
2006/06/12(月) 11:29:150202デフォルトの名無しさん
2006/06/12(月) 13:18:54module MyRandom where
import System.Random
import System.Time
import System.IO.Unsafe
getPicosec :: IO Integer
getPicosec = getClockTime >>= return . ctPicosec . toUTCTime
newStdGenFromClock :: IO StdGen
newStdGenFromClock = getPicosec >>= return . mkStdGen . fromInteger
randomsRIO :: Random a => (a, a) -> IO [a]
randomsRIO = (newStdGenFromClock >>=) . (return .) . randomRs
-- randomsRIO r = newStdGenFromClock >>= return . randomRs r
randomsIO :: Random a => IO [a]
randomsIO = newStdGenFromClock >>= return . randoms
randomsRUnsafe :: Random a => (a, a) -> [a]
randomsRUnsafe = unsafePerformIO . randomsRIO
randomsUnsafe :: Random a => [a]
randomsUnsafe = unsafePerformIO randomsIO
これをインポートして take 10 $ randomsRUnsafe (0, 5) とかすれば乱数リストが取れた。
0203デフォルトの名無しさん
2006/06/12(月) 14:24:32あり^^
0204デフォルトの名無しさん
2006/06/12(月) 17:19:48randomsRUnsafeをtakeするのをreplicateしたら全部同じリストなんですね。
0205デフォルトの名無しさん
2006/06/12(月) 19:00:590206202
2006/06/12(月) 19:06:14それはしょうがないんじゃないかと思う。
それはそれとして、
sequence $ replicate 10 $ randomsRIO (0,5) >>= print . take 15
とかやっても高々2種類でしたよ(^^;
まぁ、picosecの値が同じ間は同じ列になるわけだから当然の結果だけど。
とりあえず下のようにgetStdGen, setStdGenを利用してやるようにしたら毎回違う列になるように出来た。
newStdGenFromClock
= do { i <- getPicosec; j <- getStdGen >>= return . fst . random;
setStdGen $ mkStdGen $ fromInteger i + j; getStdGen }
0207デフォルトの名無しさん
2006/06/12(月) 19:23:45Hugsだと
Hugs.Base> "あいうえお"
"\12354\12356\12358\12360\12362"
になる。
でもロケールのエンコーディングに変換されるのでUnicode環境じゃないときびしい。
0209デフォルトの名無しさん
2006/06/12(月) 19:31:47なんで?どこでも使えるためのlocaleだと思うんだが。
0210デフォルトの名無しさん
2006/06/12(月) 22:31:09WinHugsだと
Hugs> "あいうえお"
"\642554146"
になる。
どう見てもバグ。
0211デフォルトの名無しさん
2006/06/12(月) 22:55:58WinHugs付属のhugs.exeだと
Hugs> "あいうえお"
"\130\160\130\162\130\164\130\166\130\168"
だったり。
lengthに関してはどっちも
Hugs> length "あいうえお"
10
まぁ、putStrで表示してくれるからとりあえずは使える。(GHCみたく構文解析レベルではねられるよりはマシ)
Hugs> putStr "あいうえお"
あいうえお
0212デフォルトの名無しさん
2006/06/13(火) 03:56:09Hugs.Base> putStr "あいうえお"
あいうえお
Hugs.Base> length "あいうえお"
5
Hugs.Base> "あいうえお"
"\12354\12356\12358\12360\12362"
0213デフォルトの名無しさん
2006/06/13(火) 07:31:400214デフォルトの名無しさん
2006/06/13(火) 10:29:52日本の Haskell の普及に貢献したことは忘れない。合掌。
0215デフォルトの名無しさん
2006/06/13(火) 14:13:11仕様確定して仕上げる時に、速くしたい部分をC++で
って感じで構築すればおk?
0216デフォルトの名無しさん
2006/06/13(火) 23:55:48一部wget -mしたもの持ってるけどなにか役に立つかな?
0217デフォルトの名無しさん
2006/06/14(水) 01:50:17OSMのやつ?
タイトルが気になったから、立ち読みして来た。
けど、私にはつまんなかった。
何が言いたいのか、わからんかった。
0218デフォルトの名無しさん
2006/06/14(水) 12:12:35実装を切替えることってGHC拡張の範囲でできる?
0219デフォルトの名無しさん
2006/06/14(水) 12:23:41たとえば、どんな風なことをしたい?
0220デフォルトの名無しさん
2006/06/14(水) 13:03:13-- Ordのインスタンス用実装
containsOrd :: (Ord a) => [a] -> a -> Bool
containsOrd xs = \y -> ... table上の二分探索 ...
where
table = array ... 配列を構築 ...
-- それ以外用実装
containsOther :: (Eq a) => [a] -> a -> Bool
containsOther = flip elem
contains :: (Eq a) => [a] -> a -> Bool
contains = ... aがOrdのインスタンスならcontainsOrdを、そうでないならcontainsOtherを呼ぶ ...
でも実装を考えてみたら渡すべき辞書がないから無理だな。
どっちにしてもレスありがとう。
0221デフォルトの名無しさん
2006/06/14(水) 13:06:26C++風の、特殊化とtype traitsで出来るんじゃないか?
0222デフォルトの名無しさん
2006/06/14(水) 13:28:47型クラスは実行時解決だからな。
型クラスで書いてると、ときどき全部Template Haskellで書き直したくなる。
0223デフォルトの名無しさん
2006/06/14(水) 19:02:39型や宣言を書き換えられない([d||]の中に$()が書けない)のがアレだけど。
0224デフォルトの名無しさん
2006/06/14(水) 22:16:14無名関数を演算子的に中置記法で使うことは出来ないのでしょうか?
*Main> 2 `(x y -> x + y)` 3
<interactive>:1: parse error on input `('
0225デフォルトの名無しさん
2006/06/14(水) 22:21:49バッククォートで囲めるのは単一のトークンだけ。
0226224
2006/06/14(水) 22:23:23では出来ないのですね。ありがとうございました。
0227デフォルトの名無しさん
2006/06/14(水) 22:44:080228デフォルトの名無しさん
2006/06/15(木) 08:18:12>型や宣言を書き換えられない([d||]の中に$()が書けない)のがアレだけど。
$(..)が書けないのは型宣言だけかと? 宣言に対して [|d hoge = $(...)|] は書けるっぽい。
確かに[d| data S = $(...) |]は無理。
0229デフォルトの名無しさん
2006/06/15(木) 11:17:44┏┫┃┃┃ スレ違い雑談は┃┃┃┣┓
┃┃┃┃┣┓ ここまで.┏┫┃┃┃┃
┃ ┃┃┏━━━┓┃┃ ┃
┃スレ違い ┣┫ ・∀・ ┣┫ END ┃
┗━━━━┛┗┳━┳┛┗━━━━┛
┏┻┓┃
┏━┛ ┣┻┓
┗━━━┫ ┗━┓
┗━━━┛
0230デフォルトの名無しさん
2006/06/15(木) 12:08:16下のページを参考にしているのですが、関数の合成がうまく行きません。
http://www.shido.info/hs/haskell3.html
何故なのでしょうか?
foo x y = x * y
bar x = x - 1
*Main> bar $ foo 5 2
9
*Main> (bar . foo) 5 2
<interactive>:1:
No instance for (Num (a -> a))
arising from use of `bar' at <interactive>:1
In the first argument of `(.)', namely `bar'
In the definition of `it': it = (bar . foo) 5 2
0231デフォルトの名無しさん
2006/06/15(木) 12:42:54(.)は一引数の関数しか合成できない。
0232デフォルトの名無しさん
2006/06/15(木) 12:44:30ttp://www.sampou.org/haskell/tutorial-j/functions.html
この辺でも見て、カリー化を勉強するとよろし
一応curry (bar.uncurry foo) 5 2でなんとかなる
0233230
2006/06/15(木) 13:07:17ありがとうございます。やさしい(not Easy but Gentle)Haskell入門を読んでみます。
しかし、
http://www.shido.info/hs/haskell3.html
6.3. 関数の合成
. は関数を合成します。
foo $ hoge x y ⇔ (foo . hoge) x y
このページは間違っているようですね。うーん。
0234デフォルトの名無しさん
2006/06/15(木) 13:11:230235デフォルトの名無しさん
2006/06/15(木) 13:18:40(.) :: (b->c) -> (a->b) -> a -> c
なので、bar . foo とするとbarとfooはそれぞれ1引数関数として扱われる。
barはもともと1引数なので問題ないが、fooは2引数関数( n -> n -> n )なので、
1引数関数を返す1引数関数( n -> (n -> n) )と解釈される。
その上で(.)の型に当てはめていくと、
barから、b=n, c=n
fooから、a=n, b=(n->n)
となり、bに関して矛盾が起きる。
実際にはbarの型は少し幅があるのでb=c=(n->n)として当てはめようとするんだけど、
(n->n)はその許された幅からも逸脱しちゃってるよ、とエラーメッセージを出している。
0236デフォルトの名無しさん
2006/06/15(木) 13:25:49curry, uncurryを使わなくても、 (bar .) . foo でOK。
ちなみに、fooが3引数だと、 ((bar .) .) . foo でOK。
0238デフォルトの名無しさん
2006/06/15(木) 15:52:180239デフォルトの名無しさん
2006/06/15(木) 20:10:310240デフォルトの名無しさん
2006/06/15(木) 20:30:36関数適用演算子。
f $ x = f x
右結合で優先順位0の演算子なので、括弧を省略するのに使える。例えば、
length $ filter null $ lines str
は、
length (filter null (lines str))
と同じ。
0241デフォルトの名無しさん
2006/06/15(木) 22:07:320242デフォルトの名無しさん
2006/06/16(金) 08:09:40あと map.mapとか bar.foo とか、 (.) を使う時にスペースを入れないのは流行なの?
パッケージ名の修飾と間違えそうで怖いんだが。
hoge.hs:
data Data = Data Int
fun x = x+1
ghci/hugs> hoge = Data.fun
このData.funはモジュールDataの関数funなのか Data . fun なのか判別できるのか?
やってみた。
*Main> let x = (Data.fun) 1
<interactive>:1:9:
Failed to load interface for `Data':
Could not find module `Data':
it is not a module in the current program, or in any known package.
*Main> let x = (Data . fun) 1
結論:中置演算子の . は離して書くこと。ってReportかGentle〜に書いてあった気がするけど。
$も同様。 $(...) は -fth で template haskellのspliceと間違える可能性がなくはない。 $ (...)とする。
0243デフォルトの名無しさん
2006/06/16(金) 08:32:50勉強になった
0244デフォルトの名無しさん
2006/06/16(金) 10:14:53いいのだが……
POPに描かれている「はすケロ」なる、蛙と思われるキャラの絵は何だ。
0245デフォルトの名無しさん
2006/06/16(金) 14:10:26my_length [] = 0
my_length (x:xs) = 1 + my_length xs
ここで、x:xs が()で囲われなければならないのはなぜでしょう?
私は「:」演算子が関数適用より優先順位が低いからだと思っていたのですが、
どうも違うような気がしてきました。
そもそも「:」はデータコンストラクタだということで、「ふつケル」の7章と
9章を見てみたのですが、()についての記述は見つかりませんでした。
0246デフォルトの名無しさん
2006/06/16(金) 14:56:320247デフォルトの名無しさん
2006/06/16(金) 15:13:18その理解で良いと思う。
構文的には、そこに書けるのはapat (atomic patternかな)だけだから、ということになる。
http://haskell.org/onlinereport/syntax-iso.html
0248245
2006/06/16(金) 15:20:27なるほど!ありがとうございます。
演算子の優先順位の問題なら、()の代わりに$が使えるはずだと思っていたの
ですが、それはエラーになってしまったので、間違いだったかと思い始めまし
た。
そうではなくて、パターンマッチに$が許されないからだったのですね。
0249デフォルトの名無しさん
2006/06/16(金) 15:23:38関数は小文字から始めることになっているから問題ない。
Dataという関数はありえない。
0250デフォルトの名無しさん
2006/06/16(金) 15:25:35型コンストラクタ
0251250
2006/06/16(金) 15:29:21データコンストラクタだな
0252249
2006/06/16(金) 15:55:07Data.hoge => モジュール
data.hoge => 関数合成
Data hoge => データコンストラクタ
でいいのでは?
■ このスレッドは過去ログ倉庫に格納されています