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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/06/03(土) 00:53:50
haskell.org
http://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:50
はじめに出たやつよりはましだろ。
0154デフォルトの名無しさん2006/06/10(土) 21:01:16
Haskellの勉強しようとすると、Clara Haskilのレコードを聴きだして勉強が進まない。
0155デフォルトの名無しさん2006/06/10(土) 21:06:13
なんかフジテレビに白石ひよりが出てるな
0156デフォルトの名無しさん2006/06/10(土) 22:10:28
>>152
> ふつうのHaksell
それ、パチもんだから。
0157デフォルトの名無しさん2006/06/11(日) 01:40:36
最低限の代数学のセンスないとダメだから。
無理だと思った人はとっととあきらめて。
0158デフォルトの名無しさん2006/06/11(日) 02:20:20
>>154
Haksellができたところで現実的には何も変わらんから気にするな
0159デフォルトの名無しさん2006/06/11(日) 03:10:22
変わらないなら変えるんだ!
0160デフォルトの名無しさん2006/06/11(日) 05:10:03
関数型言語やってると脳が活性化しますね。
物事を再帰関数で考える所も、ワーキングメモリ増強に良い気がします。
0161デフォルトの名無しさん2006/06/11(日) 05:11:53
concatってなんて発音するの?
コンキャット?
0162デフォルトの名無しさん2006/06/11(日) 07:10:38
辞書引きなさいよ
0163デフォルトの名無しさん2006/06/11(日) 07:35:31
分からないなら黙ってなさいよ
0164デフォルトの名無しさん2006/06/11(日) 09:52:52
分かってる人も答えなさんなよ
0165デフォルトの名無しさん2006/06/11(日) 10:00:29
>>160
再帰で考える方がワーキングメモリは少なくて済むんじゃないか。
0166デフォルトの名無しさん2006/06/11(日) 10:16:56
>>165
俺は最初再帰関数の処理手順がイメージつかなくて脳が悲鳴を上げた

脳にスタックを作るのはいい体操になると思う
0167デフォルトの名無しさん2006/06/11(日) 11:28:03
小学生ですが、小学生でも理解できるでしょうか?
0168デフォルトの名無しさん2006/06/11(日) 11:31:11
出来ない理由はない。
0169デフォルトの名無しさん2006/06/11(日) 11:32:35
このスレ住人に理解できることが小学生に理解できないわけがないだろ。
0170デフォルトの名無しさん2006/06/11(日) 11:56:23
このスレに東大生はいますか?
0171デフォルトの名無しさん2006/06/11(日) 12:03:31
何で東大生を探しているの?
0172デフォルトの名無しさん2006/06/11(日) 12:04:15
どうもこの瞬間にはいないようです。
0173デフォルトの名無しさん2006/06/11(日) 12:11:55
BBSのログは一つだけだから、瞬間には唯一人しかいないに決まってる。
0174デフォルトの名無しさん2006/06/11(日) 12:30:15
>>172≠東大生は恒真らしいということですか
0175デフォルトの名無しさん2006/06/11(日) 13:33:32
諸君、議論したまえ。
0176デフォルトの名無しさん2006/06/11(日) 13:35:11
もうすることないです
0177デフォルトの名無しさん2006/06/11(日) 15:10:26
Haskell製のテキストエディタあったろ
あれいじってなんか書け
0178デフォルトの名無しさん2006/06/11(日) 15:18:14
Haskellって案外生産性が低いんだよな。
Pythonと比べて30倍くらい時間かかる。
0179デフォルトの名無しさん2006/06/11(日) 15:26:54
>>178
今のところはね。
0180デフォルトの名無しさん2006/06/11(日) 16:05:17
VBの方が生産性高いよね。すぐに動くコードが出来上がる。
0181デフォルトの名無しさん2006/06/11(日) 16:47:36
BASICより遅いよな、ぶっちゃけ。
まあその代わり素晴らしい表現力があるが。
0182デフォルトの名無しさん2006/06/11(日) 17:08:20
haskellの最大の欠点(つかocamlもなんだけどよ)
unicode対応まだ〜?チンチン!!(AA略)

0183デフォルトの名無しさん2006/06/11(日) 18:23:35
ocaml日本語使えるじゃん
0184デフォルトの名無しさん2006/06/11(日) 19:02:14
>>183
# ["漢字文字列"] ;;
- : string list = ["\138ソ\142\154\149カ\142\154\151\241"]
↑これを使えるっていうのならね
0185デフォルトの名無しさん2006/06/11(日) 19:46:20
>>157
何の煽りか知らないけど、
代数学の知識なんて要らないんじゃ?集合論の知識すら要らないような。
モナドの話になるとちょっと代数が関わってくるけど,Haskellerならreturnが単位元な事と>>=の結合則が成り立つ事が分かっていればいい。

Haskell は
・マニュアルの読み方
・データと型の名前空間が違うということ
・構築子は大文字で,関数や型変数は小文字だということ
・演算子の中置記法
・let文の書き方
・パターンマッチの使い方
・型構築子の概念 (Either a bは a と b の 二つの「型引数」を持った型,とか)
・IOモナドの使い方 (>>=とreturnの型が分かること)

これだけわかればとりあえず使えるはず。(常識的なC,Javaに慣れていれば)
高階関数なんかは頭をひねってくれ。lisp/schemeでも使うでそ。
0186デフォルトの名無しさん2006/06/11(日) 19:51:10
特に IOモナドは,数学の概念とかは忘れて,単に
(>>=) :: 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
>>185
> Haskellerならreturnが単位元な事と>>=の結合則が成り立つ事が分かっていればいい。

代数じゃん!
0188デフォルトの名無しさん2006/06/11(日) 20:17:31
>>184
wwwwwwwwwwwwwwwwwwww
0189デフォルトの名無しさん2006/06/11(日) 21:02:09
> >>=の結合則
別に成り立たなくてもプログラムの意味は変わらないと思う
0190デフォルトの名無しさん2006/06/11(日) 21:14:34
do
 do
   a
   b
 c

do
 a
 do
   b
   c
で意味が違うのは嫌じゃないか?
0191デフォルトの名無しさん2006/06/11(日) 22:06:19
>>188
何わらってんだかしらんが、一文字を一文字として扱えない段階で話にもなってないって事じゃねぇの?
0192デフォルトの名無しさん2006/06/12(月) 00:00:00
日本語なんて使うなよ
それとも英語も出来ない人ですかw
0193デフォルトの名無しさん2006/06/12(月) 00:12:45
>>192
釣りですか?
0194デフォルトの名無しさん2006/06/12(月) 01:05:17
>>191
釣りですか?
0195デフォルトの名無しさん2006/06/12(月) 01:11:51
>>193
釣りですか?
0196デフォルトの名無しさん2006/06/12(月) 01:22:59
you
 can
  do
   shityainayo
0197デフォルトの名無しさん2006/06/12(月) 06:36:21
$! でバッチ処理的にソートさせてみたら、
なんと遅延評価させるものより遅くなった!
死にたい
0198デフォルトの名無しさん2006/06/12(月) 06:41:55
>>187
自分で一からモナドを書かない限り、代数は使わなくても済むよ〜、
と言いたかった。

もちろん知っておいた方がいいのは間違いない。
他にfoldrとfoldlは与える演算子が結合的なら結果が同じになるとか。

ただ普通にCやJavaでやっていた計算をHaskellでやる分には何も考えなくても書ける。
01991972006/06/12(月) 06:59:15
しかもメモリ馬鹿食いしてる!
0200デフォルトの名無しさん2006/06/12(月) 09:07:00
>>192
そういう煽り方しておもしろいですか?

0201デフォルトの名無しさん2006/06/12(月) 11:29:15
手軽にランダムリスト得たい時はどうしますか?
0202デフォルトの名無しさん2006/06/12(月) 13:18:54
Haskellで乱数は使ったことなかったのでちょっと試しに書いてみた。

module 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
>>202
あり^^
0204デフォルトの名無しさん2006/06/12(月) 17:19:48
>>202
randomsRUnsafeをtakeするのをreplicateしたら全部同じリストなんですね。
0205デフォルトの名無しさん2006/06/12(月) 19:00:59
nobsunの ハッカーがHaskellを使うべきでない10の理由 超ワロス
02062022006/06/12(月) 19:06:14
>>204
それはしょうがないんじゃないかと思う。

それはそれとして、
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:45
>>191
Hugsだと

Hugs.Base> "あいうえお"
"\12354\12356\12358\12360\12362"

になる。
でもロケールのエンコーディングに変換されるのでUnicode環境じゃないときびしい。
02082072006/06/12(月) 19:24:48
>>191
×でもロケールのエンコーディングに変換されるので
○でも入出力時にロケールのエンコーディングに変換されるので
0209デフォルトの名無しさん2006/06/12(月) 19:31:47
>Unicode環境じゃないときびしい。
なんで?どこでも使えるためのlocaleだと思うんだが。
0210デフォルトの名無しさん2006/06/12(月) 22:31:09
>>207
WinHugsだと

Hugs> "あいうえお"
"\642554146"

になる。
どう見てもバグ。
0211デフォルトの名無しさん2006/06/12(月) 22:55:58
>>210
WinHugs付属の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:09
Linux

Hugs.Base> putStr "あいうえお"
あいうえお
Hugs.Base> length "あいうえお"
5
Hugs.Base> "あいうえお"
"\12354\12356\12358\12360\12362"
0213デフォルトの名無しさん2006/06/13(火) 07:31:40
haskellのメッキは剥がれるのか?
0214デフォルトの名無しさん2006/06/13(火) 10:29:52
sampou.org のデータがふっとんだんだね。
日本の Haskell の普及に貢献したことは忘れない。合掌。
0215デフォルトの名無しさん2006/06/13(火) 14:13:11
仕様変更がある内はHaskellで
仕様確定して仕上げる時に、速くしたい部分をC++で
って感じで構築すればおk?
0216デフォルトの名無しさん2006/06/13(火) 23:55:48
>>214
一部wget -mしたもの持ってるけどなにか役に立つかな?
0217デフォルトの名無しさん2006/06/14(水) 01:50:17
>>205
OSMのやつ?
タイトルが気になったから、立ち読みして来た。

けど、私にはつまんなかった。
何が言いたいのか、わからんかった。
0218デフォルトの名無しさん2006/06/14(水) 12:12:35
多相的な関数について、型変数が特定のクラスのインスタンスであるかどうかによって
実装を切替えることってGHC拡張の範囲でできる?
0219デフォルトの名無しさん2006/06/14(水) 12:23:41
>>218
たとえば、どんな風なことをしたい?
0220デフォルトの名無しさん2006/06/14(水) 13:03:13
普段は線形探索だけど、Ordのインスタンスに対しては二分探索を使う、とか。

-- 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:26
コンパイル時切り替えなら、
C++風の、特殊化とtype traitsで出来るんじゃないか?
0222デフォルトの名無しさん2006/06/14(水) 13:28:47
>>221
型クラスは実行時解決だからな。
型クラスで書いてると、ときどき全部Template Haskellで書き直したくなる。
0223デフォルトの名無しさん2006/06/14(水) 19:02:39
Template Haskell良さそうね。
型や宣言を書き換えられない([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
>>224
バッククォートで囲めるのは単一のトークンだけ。
02262242006/06/14(水) 22:23:23
おお、そんな制約が。
では出来ないのですね。ありがとうございました。
0227デフォルトの名無しさん2006/06/14(水) 22:44:08
the Reportじっくり追えば分かるね。
0228デフォルトの名無しさん2006/06/15(木) 08:18:12
>>223
>型や宣言を書き換えられない([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
>>230
(.)は一引数の関数しか合成できない。
0232デフォルトの名無しさん2006/06/15(木) 12:44:30
>>230
ttp://www.sampou.org/haskell/tutorial-j/functions.html
この辺でも見て、カリー化を勉強するとよろし
一応curry (bar.uncurry foo) 5 2でなんとかなる
02332302006/06/15(木) 13:07:17
>>231-232
ありがとうございます。やさしい(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:23
報告しといた。
0235デフォルトの名無しさん2006/06/15(木) 13:18:40
>>230
(.) :: (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:49
>>232
curry, uncurryを使わなくても、 (bar .) . foo でOK。
ちなみに、fooが3引数だと、 ((bar .) .) . foo でOK。
02372322006/06/15(木) 15:15:22
>>236
勉強になった
0238デフォルトの名無しさん2006/06/15(木) 15:52:18
な、なんだっ(ry
0239デフォルトの名無しさん2006/06/15(木) 20:10:31
$ってなに?
0240デフォルトの名無しさん2006/06/15(木) 20:30:36
>>239
関数適用演算子。
f $ x = f x
右結合で優先順位0の演算子なので、括弧を省略するのに使える。例えば、
length $ filter null $ lines str
は、
length (filter null (lines str))
と同じ。
0241デフォルトの名無しさん2006/06/15(木) 22:07:32
論理学での記述でいうドットかな。
0242デフォルトの名無しさん2006/06/16(金) 08:09:40
Template Haskellの話題がスレ違いだとはorz

あと 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
>>242
勉強になった
0244デフォルトの名無しさん2006/06/16(金) 10:14:53
ジュンク堂池袋本店、ふつケルと入門Haskellが並んで平積み、は
いいのだが……

POPに描かれている「はすケロ」なる、蛙と思われるキャラの絵は何だ。
0245デフォルトの名無しさん2006/06/16(金) 14:10:26
プリミティブですみませんが、質問です。

my_length [] = 0
my_length (x:xs) = 1 + my_length xs

ここで、x:xs が()で囲われなければならないのはなぜでしょう?

私は「:」演算子が関数適用より優先順位が低いからだと思っていたのですが、
どうも違うような気がしてきました。

そもそも「:」はデータコンストラクタだということで、「ふつケル」の7章と
9章を見てみたのですが、()についての記述は見つかりませんでした。
0246デフォルトの名無しさん2006/06/16(金) 14:56:32
>>244はすケロタンの画像きぼんぬ
0247デフォルトの名無しさん2006/06/16(金) 15:13:18
>私は「:」演算子が関数適用より優先順位が低いからだと思っていたのですが、
その理解で良いと思う。
構文的には、そこに書けるのはapat (atomic patternかな)だけだから、ということになる。
http://haskell.org/onlinereport/syntax-iso.html
02482452006/06/16(金) 15:20:27
>>247
なるほど!ありがとうございます。
演算子の優先順位の問題なら、()の代わりに$が使えるはずだと思っていたの
ですが、それはエラーになってしまったので、間違いだったかと思い始めまし
た。
そうではなくて、パターンマッチに$が許されないからだったのですね。
0249デフォルトの名無しさん2006/06/16(金) 15:23:38
>>242
関数は小文字から始めることになっているから問題ない。
Dataという関数はありえない。
0250デフォルトの名無しさん2006/06/16(金) 15:25:35
>249
型コンストラクタ
02512502006/06/16(金) 15:29:21
間違えた。
データコンストラクタだな
02522492006/06/16(金) 15:55:07
データコンストラクタを(.)で繋ぐことってないような
 Data.hoge  =>  モジュール
 data.hoge  =>  関数合成
 Data hoge  =>  データコンストラクタ
でいいのでは?
■ このスレッドは過去ログ倉庫に格納されています