関数型プログラミング言語Haskell
■ このスレッドは過去ログ倉庫に格納されています
0001潜伏していた1
NGNG前スレ
http://pc.2ch.net/test/read.cgi/tech/996131288/l50
関連 >>2 以降
0666デフォルトの名無しさん
NGNGhttp://www.sampou.org/haskell ならサーバマシンの調子が悪いそうです
0667デフォルトの名無しさん
NGNG復活したようです。
>>665
いないんじゃないですか。人少なそうだし。
俺は、外界との繋がりはsystem :: String -> IO ExitCodeくらいしか知らない。
0668659=665
NGNGでも、*.hiをバイナリ検索しても、IsDBCSLeadByteはインポートされて無いようです。
(CharNextとか、代用できそうなAPIも同様)
これは、Haskellで全角文字を扱うなというお告げでしょうか…
0669デフォルトの名無しさん
NGNGIsDBCSLeadByteってwindowsのAPI?
そういうものはそのライブラリとリンクしてつかうんじゃないのかな。
haskellに入ってるわけがないというか。
http://www.haskell.org/libraries/
のInterfacing with other Languages and Systemsとか。
0670デフォルトの名無しさん
NGNG>(真似たらできました)
おー、あなたも私から見たらすどい。
よろしければ、MessageBoxを出すコードをこのスレに張って
共有していただければありがたいです。
0671デフォルトの名無しさん
NGNGいや、GHC(Win版)には既にWin32 API(の一部)のHaskell用インポートが付いてるんですよ。
>>670
どーせ丸写しなので、いくらでも共有しましょう。
import Win32
main = messageBox nullHANDLE "Text" "Title" mB_OK
たった二行。
コンパイル時に -package win32オプションが必要です。
(win32ディレクトリ以下はデフォルトでは見てくれないので)
↓見つけたページ
http://www.haskell.org/pipermail/glasgow-haskell-users/2002-March/003110.html
なお、同じようにしてMessageBeepを呼ぼうとしましたが、挫折中です。
0672デフォルトの名無しさん
NGNGあ、でもリンク先のFFIとか使えばできそう?できるのか俺に?
…ありがとうございます
0673デフォルトの名無しさん
NGNG使おうとしたけど何だかよくわからんかった。(窓使いです)
0674デフォルトの名無しさん
NGNGttp://www.sampou.org/haskell/report-j/basic.html
>6.1.2 文字と文字列
>文字型 Char は列挙型のひとつで、16 bit の値からなり、Unicode 標準 [10] に準拠する。
Unicodeなので要らないのでは?
ちゃんと実装されているならばだが。
0675デフォルトの名無しさん
NGNG内部ではUnicodeかもしれないけど、全角文字をgetCharで読むと二回に分けて来るんですよ…
0676デフォルトの名無しさん
NGNGUnicodeとその(バイトでの)エンコーディングは別物だ。
0677デフォルトの名無しさん
NGNG実際
I/O functionsがbyte読んでそれをかえすだけだから、
Charが16ビットである意味がないんだよな。
謎の設計。
0678デフォルトの名無しさん
NGNG0679デフォルトの名無しさん
NGNGリストはモナドだから。
0681デフォルトの名無しさん
NGNGなんでリストがモナドなのがいまいちよく分からん。
0682デフォルトの名無しさん
NGNG0683デフォルトの名無しさん
NGNG書いた後気づいたのだが return [3,4] >> [1,2] も [1,2] 返すのか
() がポイントではなく return の方がポイントだった
かきまぜてスマン
0684デフォルトの名無しさん
NGNG0685デフォルトの名無しさん
NGNG>>の型からわかる型推論。
0686デフォルトの名無しさん
NGNG0687デフォルトの名無しさん
NGNG参照透明性からいって 'a' が入力されたからといって IO 'a' が返るわけじゃないんだよね
たびたび出る話題でスマンが毎回納得にいたらない
0688デフォルトの名無しさん
NGNG0689デフォルトの名無しさん
NGNG意味不明。IO Charだけど?
0690デフォルトの名無しさん
NGNG強いて言えば IO 'a'だろうが、それで参照透明性に何の問題が?
0691デフォルトの名無しさん
NGNGという気がする.モナドを理解するためには,次の論文を読むのが吉かと.
Wadler, P. : Monads for functional programming
0693デフォルトの名無しさん
NGNGそうそう.
0694デフォルトの名無しさん
NGNG実は暗黙のworldが渡されていて暗黙の新しいworldも返されている?
0695デフォルトの名無しさん
NGNG0696デフォルトの名無しさん
NGNG何か問題があるような気もするがー。
0697デフォルトの名無しさん
NGNG0698デフォルトの名無しさん
NGNG_,..............._,.......
,ノ⌒::::::::::::::::::::::::::::::::::::⌒ヽ_
_ノ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::ヾ、
(::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)
_ノ:::::::::::::::;ヘ::::::::::ノ⌒ヽ:::::::::::::::::::::::::::::::::)
(::::::::::::::::::/  ̄ , ‐-、 |::::::::::::::::::::::::::::::::) / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
(:::::::::::::/ヽj _/ -‐-、 |::::::::::::::::::::::::::::::::) | トリックだ。
):::::::::ヾllli_、_,;iiiillllllllli <::::::;へ:::::::::::::::::( |
(::::::::::::/`i´ ,└=゚'┘ |::::| 6 |:::::::::::::::::::} < 副作用があるように見えているに
`〜、 ゝ| _コ、_、 /|::::| ソ/::::::::::;〜" | 過ぎん。
ヾ|||ll|||||||||||l〉| 三ー'〜〜" |
|||:二三|||| l ,三 ヽ、 \______________
|l ⌒ ||| :// ヽ=、-、_
|l、:( : : ||/ / ヽ, |  ̄\
/  ̄ / ノ / \
0699デフォルトの名無しさん
NGNGreturn () >> [1,2,3]
後ろがリストなので、これはリストモナド
returnを外して、>> を >>= に変換すると、
[()] >>= (\x -> [1,2,3])
前のリストの要素それぞれに対して後ろの関数を呼んで、その結果を連結したものがこの式の値なので、
(\x -> [1,2,3]) ()
[1,2,3]
0700デフォルトの名無しさん
NGNGその通り。IO a はHaskellの側から見ると、
data IO a = IO (World -> (a, World))
このような構造になっていて、実行結果がIOだった場合に、表示する前にWorldが渡されて実行される。
実際はそんな面倒なことしていないと思うけどね。
0701デフォルトの名無しさん
NGNGでっかい合成関数を組み立てて、最後に一括して実行してるようなイメージでいいのでしょうか?→モナド
(と同時に、実装までそうなってないよなあと信じたい)
0702デフォルトの名無しさん
NGNGモナドを使えば副作用は「ある」というべきだろう。
たとえばモナドを利用したカウンタを利用して、
あるいは、ファイルに1, 2, ...と書き込んでループをつくれば、
あきらかにそこには副作用があるわけだ。
むしろWorldを変化させながら渡し続けるという発想の転換で(言語に対し)
無いように見せかけているだけだ。人間にとっては副作用は存在する。
0703デフォルトの名無しさん
NGNGあるように見せかけているだけだろ?
そうじゃなきゃモナドの意味がない
0704山崎 渉
NGNG__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
0705デフォルトの名無しさん
NGNGあと、遅延実行されるのでそう実装しても効率は悪くならないと思う。
0706デフォルトの名無しさん
NGNG逆だよ。というか循環論法。
そもそも関数型言語には本来副作用は存在し得ない。状態ってものが無いからね。
しかし、特に外部とアクセスするプログラムのためには副作用が必要だ。
関数型言語と、その副作用をともなう処理を、
副作用の種類(IOとか)毎の(内部状態を保持する)モナドを導入することで*分離*してるだけだ。
0707デフォルトの名無しさん
NGNG701のイメージはあってるが、
> あと、遅延実行されるのでそう実装しても効率は悪くならないと思う。
遅延実行だからこそそういう式の組み立てと式の保存をやらないといけないわけで、
むしろ遅延評価だからと言ってそういう実装をするととんでもないことになる
というべき。
通常の式の評価でも下手に(末尾)再帰すると未評価の式の列が莫大になって
すぐオーバーフローする。
0708701
NGNGデータ型としてのモナドは、要するにC++のクラスtemplate、のようなもの…ですよね?
ということは、IO a -> aな関数が記述不可能なのは、言語の外を相手にしたIOモナドに限った制限で
一般的にはそんな制限は無い、で合ってます?
簡単なサンプルコードどこかにないかな…
0709デフォルトの名無しさん
NGNGリストから成分を抽出できるでしょ。
0710デフォルトの名無しさん
NGNGありがとです。
で、>>681氏と同じ疑問に行き当たるわけですが…
リストが状態を持っているとは思えないのですが、なぜモナド?
(a, b)とか他の一般の構造化型はモナドじゃ無いですよね。
0711デフォルトの名無しさん
NGNGリストを丸ごと全部で値と思わずに一部だけ更新したいんじゃない?
一部だけ更新するような操作には普通副作用がある。
…違うかな?
0712デフォルトの名無しさん
NGNG(a,b)とか一般の構造型はコンテナの中身の個数が1個ではない定数なのでうまく
モナド演算を定義できないような気がする
リストモナドの中身は任意個数。IOモナドは1個固定。
0713デフォルトの名無しさん
NGNGえーと、要するに、必然性は無いけど、
モナドということにすると [a] >>= (\e -> return (f e)) みたいな便利機能として使えるので
モナドということにしてある、ということですか。
>>711
よく見て無いのですが、ライブラリリファレンスにMutable ArraysとしてIOArrayが書かれてますので、
もしリストモナドで一部の更新が可能なら、こんなもの用意しないと思うので、それは違う気が
(我ながら無茶苦茶な論法だ…)
0714デフォルトの名無しさん
NGNG0715デフォルトの名無しさん
NGNGすまんが、そういうふうにする以外の方法が自分には想像できない。
doも普通の再帰なので問題はなさそうだが?
>>711
リストモナド≒内包表記
副作用を発生できるモナドはIOモナドだけです。
>>710
ListとMaybeだけだね。
試しに、(a, b) でMonadを作ってみたが…きつい。
---
instance Monad ((,) a) where
(>>=) (sub, main) f = (sub, main') where
(sub', main') = f main
return main = (bottom, main)
bottom = bottom
test = do x <- (("a", 2), 1)
y <- return $ x+1
return $ y*2
---
*Main> test
(("a",2),4)
0716デフォルトの名無しさん
NGNG「型構築子」IO はモナドだけど IO a はモナドじゃないよ。
「型構築子」[] はモナドだけど [a] はモナドじゃないよ。
0717デフォルトの名無しさん
NGNGhaskellのリストやアレイはは一部を変更すると全部コピー。
というのは、そのデータ(リスト等)が他の場所で使われるかもしれないから。
一部を変更したということがそのデータを使うプログラムの他の部分にも
わからないといけない。
そのためには、使う部分全部をそのデータの内部状態をあらわすモナドでくるんで
おく必要がある。
# 変更し終わったら、それはモナドの外に出してもいい。
>>715
701の件については、誤読していた。それ以降の式、ってのが何を指すのかわからない。
それはともかくとして、
(IO/状態)モナド内の計算の実行は、手続き型と同様にできるとおもうけど。
> 副作用を発生できるモナドはIOモナドだけです。
haskellプログラムがわからみればIOも他のモナドもかわらない。
プログラマから見たときも結局は同じこと。謎の内部状態をもつ
モナドを受渡しながら処理を順次実行するわけだから。
内部で定義されたモナドでもそのモナドの性質をみとおさなければ、
副作用と同様でしょう。
0718デフォルトの名無しさん
NGNG副作用が出るわけで、関数型言語では一般にはそれができない。
だが、その副作用/状態を追跡するモナド(STArray,IOArray等)を引数と
して渡し続けながらの順次計算であれば一部変更もできるわけだ。
0719デフォルトの名無しさん
NGNG「データ構築子」はファーストクラスだけど
「型構築子」はファーストクラスじゃないよ。
0720デフォルトの名無しさん
NGNGモナドは「型構築子」の性質であって、データの性質じゃないよ。
0721デフォルトの名無しさん
NGNGまず、すまんかった。
確かに中身を見なければ副作用を起こすことは可能だ。そちらの言う通り。
以降の式だが、自分は a >>= (\x -> b) の式に出てくるλのことだと思っている。
そして、715のそういうふうにとは、どでかい合成関数を作ってからそれを実行するということ。
もちろん、遅延実行されるので、少し作ってはそれを実行してというふうになると思っているが。
>(IO/状態)モナド内の計算の実行は、手続き型と同様にできるとおもうけど。
main = sequence_ $ reverse $ [putStr "\n", putStr "a", putStr "b"]
こう言うのはどうする…?
…特殊すぎるか。他は最適化されててもおかしくないやね。
>>718
少なくともIOArrayはIOモナドの一部であってモナドそのものではないと思うが。
>>719
しかし少なくともカリー化はされている。
0722デフォルトの名無しさん
NGNGサンプルとして活用させていただきます
で、勝手にインデント。
module Main where
instance Monad ((,) a) where
(>>=) (sub, main) f = (sub, main') where
(sub', main') = f main
return main = (bottom, main)
bottom = bottom
test = do
x <- (("a", 2), 1)
y <- return $ x+1
return $ y*2
>>721
表現が悪くて申し訳ないです。そのつもりでした。do A; B… と書いた時のB以降です。
0723デフォルトの名無しさん
NGNGinstance Monad Id where
Id x >>= f = f x
return = Id
foo :: Int -> Id Int
foo arg =
do { x <- ID arg
; x <- ID (x * 2)
; x <- ID (x + 1)
; return x }
というHaskell のプログラムと、
int
foo (int arg)
{
int x;
x = arg;
x = x * 2;
x = x + 1;
return x;
}
は、そっくり。上は副作用をつかってないですけど、
下は副作用をつかっています。
そんだけ。
int
0724デフォルトの名無しさん
NGNGID じゃなくて Id
0725デフォルトの名無しさん
NGNG#include "hsFFI.h"
#include <stdio.h>
void __stdcall print_hex(HsInt a)
{
printf("%x", a);
}
foreign import stdcall "print_hex" printHex :: Int -> IO ()
main :: IO ()
main = do printHex 1234
>ghc ffi.hs ffi_c.hc -fglasgow-exts
Warning: retaining unknown function `_print_hex@4' in output from C compiler
動くんですけど、このWarningが消せない…
0726デフォルトの名無しさん
NGNG> 以降の式だが、自分は a >>= (\x -> b) の式に出てくるλのことだと思っている。
> そして、715のそういうふうにとは、どでかい合成関数を作ってからそれを実行するということ。
よくわからない。ダイナミックに関数を作ると?
> ...
> main = sequence_ $ reverse $ [putStr "\n", putStr "a", putStr "b"]
関数ポインタの配列をつくっておいて並べ替えるのかな。
>>721
> 少なくともIOArrayはIOモナドの一部であってモナドそのものではないと思うが。
確かに、モナドはそれぞれIOとSTだ。
モナドの一部っていうのもよくわからないが…
monad-awareという感じか。
0727デフォルトの名無しさん
NGNG__stdcall -> ccall、ffi_c.hc->ffi_c.c
で
ghc -ffi ffi.hs ffi_c.c
とすると何のWarningもなくコンパイルを通った(Windowsではない)。
0728デフォルトの名無しさん
NGNG5000円くらいまでなら買うからさ。
和書ないとやる気が出ねぇし、普及なんて夢のまた夢だよ。
0729デフォルトの名無しさん
NGNG0730デフォルトの名無しさん
NGNG拡張子を変えたら警告が出なくなりました。
よくよく見てみれば.hcってコンパイラが生成したCソース用の拡張子…
どうも、お騒がせしました。
0731デフォルトの名無しさん
NGNGくしゃみが出るくらいに香辛料の効いたカレーを“Haskell Curry”と云う!?
0732デフォルトの名無しさん
NGNG>よくわからない。ダイナミックに関数を作ると?
その通り。 (.) が関数を合成するのと同じように。
>関数ポインタの配列をつくっておいて並べ替えるのかな。
引数等を保存しておく必要があるので、それをすると、λと変わらないと思う。
>>722
無理しているので、return a >>= k = k a が成り立たなくなってたりしているので注意。
ついでに、前に作ったモナドをどうぞ。
面倒を少し減らす程度のものですが。
---
module Main where
--type ReadS a = String -> [(a,String)]
newtype ReadR v = ReadR { runr :: ReadS v}
instance Monad ReadR where
ReadR r >>= fr = ReadR (\str -> [ret| (v,str') <- r str, ret <- fr v `runr` str'])
return v = ReadR (\str -> [(v, str)])
rread :: (Read a) => ReadR a
rread = ReadR reads
rlex :: ReadR String
rlex = ReadR lex
test :: String -> (Int,String)
test str = head test' where
test' = do rread
`runr` str
---
Main> test "125 "
(125," ")
0733デフォルトの名無しさん
NGNG毎回の let (r2, g2) = random g1 in … 数字は使うたびに増やす…が面倒だったので、
モナドにすれば好きな時に r2 <- nextRandom とか書けるのかなあ、とか思ったり。
(既にあるのかもしれませんが)
>>732
うう、ありがとうございます。しかし、私のレベルでは何をやっているのかと用途の両方がわかりません…。
0734デフォルトの名無しさん
NGNG|無理しているので、return a >>= k = k a が成り立たなくなってたりしているので注意。
モナドの法則を満たさなくてモナドといえるの?
0735デフォルトの名無しさん
NGNGimport Random
data RandomProgression r a = RP (r -> (a, r))
nextRandom :: (RandomGen r, Random a) => RandomProgression r a
nextRandom = RP (\r -> random r)
instance Monad RandomProgression r a where
--(>>=) :: RandomProgression r a -> (a -> RandomProgression r b) -> RandomProgression r b
RP x >>= f =
RP (\r ->
let (a, r') = x r in
let RP b = f a in
b r')
--return :: a -> RandomProgression r a
return value = RP (\r -> (value, r))
書いてみました…instanceでエラーが出ます…わかりません…
↓こんな風に使えたらいいなと思ってる
let (answer, g) = (do a <- nextRandom; return (a `mod` 10)) (mkStdGen 100)
0736デフォルトの名無しさん
NGNGinstance Monad (RandomProgression r) where
実行用に
eval :: (RandomGen r) => RandomProgression r a -> r -> (a, r)
eval (RP e) r = e r
書き足して
RandomProgression> eval((do x <- nextRandom; return (x `mod` 10)) :: RandomProgression StdGen Int) (mkStdGen 10)
(7,432453652 1655838864)
動いたー!
どうも、スレ汚しごめんなさい
0737デフォルトの名無しさん
NGNGそんなことをする必要はない。
randoms (mkStdGen 1) ::[Int]
のようにして無限乱数列が作れるのだから。
Make use of the power of lazy evaluation !
# あとはそれにmapでもなんでもして加工すればいい。
0738デフォルトの名無しさん
NGNG0739デフォルトの名無しさん
NGNGなるほど!遅延評価を忘れてました。
しかしそれでも2個の乱数を取ってきたい時は、let (r1:r2:rs') = rs (以降はrs'から取る) みたく
乱数列を意識して渡していかないといけないような。いや、ずっと書きやすいではありますが。
0740デフォルトの名無しさん
NGNG知らん。気になるのなら、たとえば、こうすればちゃんとモナドになる。
module Main where
instance (Num a) => Monad ((,) a) where
(>>=) (sub, main) f = (sub+sub', main') where
(sub', main') = f main
return main = (0, main)
>>733
まずちょっと修正...スマソ。
import Monad -- 追加
instance Monad ReadR where
ReadR r >>= fr = ReadR (\str -> [ret| (v,str') <- r str, ret <- fr v `runr` str'])
return v = ReadR (\str -> [(v, str)])
fail s = mzero -- 以下追加
instance MonadPlus ReadR where
mzero = ReadR (\s -> [])
mplus (ReadR f) (ReadR g) = ReadR (\s -> f s ++ g s)
用途としては、下のようなコード(やさしいHaskell 8.3節からコピペ)のtuvwxのような変数を書かなくてもよくすること。それだけです。
>readsTree :: (Read a) => ReadS (Tree a)
>readsTree s = [(Branch l r, x) | ("<", t) <- lex s,
> (l, u) <- readsTree t,
> ("|", v) <- lex u,
> (r, w) <- readsTree v,
> (">", x) <- lex w]
> ++
> [(Leaf x, t) | (x, t) <- reads s]
0741デフォルトの名無しさん
NGNG>rreadTree :: (Read a) => ReadR (Tree a)
>readsTree s = rreadTree `runr` s
>rreadTree = do "[" <- rlex
> l <- rreadTree
> "|" <- rlex
> r <- rreadTree
> "]" <- rlex
> return $ Branch l r
> `mplus`
> do x <- rread
> return $ Leaf x
0742デフォルトの名無しさん
NGNGなんかまだ手続き型の頭のような気がする:)
関数型だったら結局繰り返しは再帰で書くんだから、
結局こんな感じになると思う。
f 0 result rs = result
f n result (r1:r2:rs) = f (n - 1) (g r1 r2 result) rs
# f 10 [] randomlist のように使う。
# g で欲しいものを計算。
0743デフォルトの名無しさん
NGNG0744デフォルトの名無しさん
NGNGNum a が気になる
0745デフォルトの名無しさん
NGNGVariable not in scopeと言われるのですが
0746デフォルトの名無しさん
NGNG気にするな。
0747デフォルトの名無しさん
NGNGfromInteger じゃだめなの?
今のHaskell 98 の Prelude には fromInt は無いのでは。
0748デフォルトの名無しさん
NGNGいえ、Intからの変換にfromInteger (toInteger n)と書くのが冗長な気がしただけです。
0749デフォルトの名無しさん
NGNGEnum クラスのメソッドが使えるのでわ。
toEnum :: Int -> a
fromEnum :: a -> Int
0750デフォルトの名無しさん
NGNGFloatやDouble…のつもりでしたが、それらもtoEnumでいけるのですね。
ありがとうございます。そして遅レスごめんなさい
0751デフォルトの名無しさん
NGNGけど、それ以外のモナドがワカンネ。
ライブラリ読んでみたりしたけど激むず。
モナド難しいですね。
ニセ手続き型を理解したあとは、どうしたらよいのでしょうか
0752デフォルトの名無しさん
NGNGmatchRegex (mkRegex "abc") "xabcx"
=> Just []
matchRegexAll (mkRegex "abc") "xabcx"
=> Just ("x","abc","x",[])
これってバグ?
0753デフォルトの名無しさん
NGNGmatchRegexAll (mkRegex "abc") "xabcx"
=> Just ("","abc","x",[])
0754デフォルトの名無しさん
NGNG実行効率周りとか。
0755デフォルトの名無しさん
NGNG0756デフォルトの名無しさん
NGNGいただきました
0757デフォルトの名無しさん
NGNG2000年あたりに出版された本で勉強しようかと思っているのですが、それいらい大きく変わったとか、
近いうちに大きく変わるとか、ありますか?
0758デフォルトの名無しさん
NGNG処理系によっては独自拡張があることも。
0759デフォルトの名無しさん
NGNGサンクスコ。
言語仕様は大きく変わってないから、そのころの本で勉強しても問題ないということですね。
がんばって勉強してみます。
(関数型言語は使ったことがないから、なじめるかわからないけど)
0760デフォルトの名無しさん
NGNGライブラリがかなり違うような気がする。
ライブラリは階層化ライブラリ(Data.Listとか)
で決まりでいいのだろうか。
標準ライブラリ以外になると混沌としか言い様がない
0761デフォルトの名無しさん
NGNG0762デフォルトの名無しさん
NGNGここにあるのが標準ライブラリーで、足りない部分は、
http://www.haskell.org/libraries/
から探すとか、自作するということですか?
http://www.haskell.org/ghc/docs/latest/html/libraries.html
で、これが HUGS についてくるライブラリー群?
0763デフォルトの名無しさん
NGNGhttp://cvs.haskell.org/Hugs/pages/hugsman/libs.html
GHCは5.04.1=>6.0でライブラリ関係が少し変わっているような気がする。
0764デフォルトの名無しさん
NGNG0765デフォルトの名無しさん
NGNG↑赤黒木の実装に感動。
だれか、コンパクトなdelete実装しれ!
■ このスレッドは過去ログ倉庫に格納されています