関数型プログラミング言語Haskell
■ このスレッドは過去ログ倉庫に格納されています
0001潜伏していた1
NGNG前スレ
http://pc.2ch.net/test/read.cgi/tech/996131288/l50
関連 >>2 以降
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実装しれ!
0766山崎 渉
NGNG│ ^ ^ │<これからも僕を応援して下さいね(^^)。
⊂| |つ
(_)(_) 山崎パン
0767デフォルトの名無しさん
NGNG0768デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています