1 名前:デフォルトの名無しさん mailto:sage [2007/08/02(木) 14:03:05 ] MSResearchから出てきた.NETで使える関数型言語のひとつF# OCAMLの流れを汲むこの言語、いろいろと面白そうなことができそう。 まだまだ英語の情報しかないこの言語について、幅広く語れ。 research.microsoft.com/fsharp/fsharp.aspx
151 名前:名無しさん♯ mailto:sage [2007/11/21(水) 08:05:42 ] Asyncを単純化するとこんな感じなのかな?( ´・ω・) #light type Async<'a> = Async of (('a -> unit) * (exn -> unit) -> unit) with static member Run (Async x) = x let unit a = Async (fun (cont, _) -> cont a) let bind m k = Async (fun (cont, econt) -> let cnext = fun a -> try Async.Run (k a) (cont, econt) with exn -> econt exn Async.Run m (cnext, econt)) で、実際にはここでのunit→resultPrim, bind→bindAsyncPrim相当でしかなくて、 これにキャンセルサポート(AsyncGroup)を追加してはじめてresultAsync, bindAsync相当になる、と。 モナドの定義自体にはスレッド云々は関係なくて、モナドを起動する側(Run, Spawn)の方で スレッドに結びつけてる、と。 これをC#で表現するのはめんどいのう。(´・ω・`)
152 名前:デフォルトの名無しさん [2007/11/21(水) 13:31:20 ] 関数型言語は図で説明できますか? フローチャートのように。 それが出来ないと、企業で使うのは難しいと思う。
153 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 13:48:56 ] フローチャート(笑)
154 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 13:53:48 ] 次の質問をどうぞ
155 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 14:30:48 ] 質問が正確じゃないな。 「Javaはむずかしすぎて使えません!」とギャグでなく主張する ド低脳にとっては関数型言語のほうが簡単なのですか? そうでないと、ドカタが使うのは難しいと思う。 こうだろ。
156 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 14:38:19 ] おもしろくないよ
157 名前:名無しさん♯ mailto:sage [2007/11/21(水) 21:33:54 ] あ、>>151 間違えとる。(´・ω・`) Async.Runは Async<'a> -> 'a にしないとダメなのか・・・。 >>151 の実装は flip asyncApp 相当に過ぎないか。
158 名前:名無しさん♯ mailto:sage [2007/11/22(木) 01:13:05 ] うーん、やっぱりキャンセルサポートなしでAsync.Runまで作っても複雑になるなあ・・・。 #light type Async<'a> = Async of (('a -> unit) * (exn -> unit) -> unit) let app (Async x) = x let unit a = Async (fun (cont, _) -> cont a) let bind m k = Async (fun (cont, econt) -> let c = fun a -> try app (k a) (cont, econt) with exn -> econt exn app m (c, econt)) let catch p = Async (fun (cont, _) -> app p (cont << Choice2_1, cont << Choice2_2)) let start p = app p ((fun () -> ()), (fun exn -> raise exn)) type Async<'a> with static member Run p = let res = ref None // val res : Choice<'a, exn> option ref let cont = fun r -> res := Some r; unit () start (bind (catch p) cont) match Option.get !res with | Choice2_1 a -> a | Choice2_2 exn -> raise exn これでAsync.Spawn, Async.Parallelまで挑戦するのは無理ぽ。(´・ω・`)
159 名前:デフォルトの名無しさん [2007/11/22(木) 12:12:02 ] 1.9.3.6リリース
160 名前:デフォルトの名無しさん [2007/11/22(木) 23:56:53 ] >153-154 図星だったようだね。
161 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:06:19 ] ?
162 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 01:28:54 ] 政治的な理由で図が必要なら、Executable UMLでも 使ってれば? あと>>155 が答え。
163 名前:名無しさん♯ mailto:sage [2007/11/23(金) 12:20:33 ] CPSだとアピールするよう、>>158 のstartをプチ改良。w let id x = x let start p = app p (id, (fun exn -> raise exn))
164 名前:名無しさん♯ mailto:sage [2007/11/23(金) 17:12:31 ] これはすばらしすぎるwww ttp://channel9.msdn.com/Showpost.aspx?postid=358968 コメント欄もなかなか熱い。(;^ω^)
165 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 01:29:29 ] もうちょっとHaskellよりなOCamlがいいと思う
166 名前:デフォルトの名無しさん mailto:sage [2007/11/24(土) 01:46:59 ] OCamlは副作用に対して寛大で、保守性や開発効率を保ったまま言語仕様を定めるのが忙しくて 165の様な要望に対しては手一杯
167 名前:名無しさん♯ mailto:sage [2007/11/27(火) 22:37:56 ] F#のオブジェクト機能をちょっとまじめに使ってみますた。( ゚д゚) ttp://cid-c42499cb3a347006.skydrive.live.com/self.aspx/Public/DLRSample.fs
168 名前:デフォルトの名無しさん [2007/11/28(水) 01:53:52 ] 日本語の解説はないの? htmlは読みにくいからpdfのドキュメントはないの?
169 名前:名無しさん♯ mailto:sage [2007/11/28(水) 17:21:32 ] 両方ともにすばらしい。(´ー`) (.ppt注意) ttp://qcon.infoq.com/sanfrancisco/file?path=/QConSF2007/slides/public/ErikMeijer_LINQIntro.ppt ttp://qcon.infoq.com/sanfrancisco/file?path=/QConSF2007/slides/public/ErikMeijer_Confessions.ppt モナドの観点では、LINQの標準クエリ演算子で最重要なのは実は SelectMany なのね。 >>168 日本語の解説は見たことないです。 英語のなら最近すごくいい入門記事が出ましたが・・・。 ttp://tomasp.net/articles/fsharp-i-introduction/article.pdf
170 名前:デフォルトの名無しさん mailto:sage [2007/11/28(水) 21:07:15 ] >>169 モンドリアン風なのが気に入ったw
171 名前:デフォルトの名無しさん [2007/11/29(木) 01:54:58 ] F#がC#より優れている点ってあるの? すべてにおいてC#が優っているように思えるのだが。
172 名前:デフォルトの名無しさん mailto:sage [2007/11/29(木) 02:04:46 ] んじゃC#使えばいいじゃにあか
173 名前:デフォルトの名無しさん [2007/11/29(木) 02:06:18 ] そうだけど何かメリットがあるならF#を使ってみようかと思って。 無いなら使わないけど。
174 名前:デフォルトの名無しさん mailto:sage [2007/11/29(木) 04:51:48 ] F#とC#は使い所が違うんじゃないかな
175 名前:デフォルトの名無しさん mailto:sage [2007/11/29(木) 05:38:33 ] (::)が関数として使えないんだけどそういうもん?
176 名前:デフォルトの名無しさん [2007/11/29(木) 20:23:52 ] F#の機能とかっていずれC#も取り込みそうな気がする。C#って何気に巨大言語だよね。
177 名前:デフォルトの名無しさん mailto:sage [2007/11/29(木) 20:49:05 ] へじたんの夢の固まりだからな
178 名前:デフォルトの名無しさん [2007/11/29(木) 21:22:37 ] C#でできることすべてはF#でできない。 F#でできることすべてはC#でできる。
179 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 01:29:16 ] 逆だろ
180 名前:デフォルトの名無しさん [2007/11/30(金) 01:30:02 ] 逆じゃない。
181 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 01:41:23 ] C#、F#でできることの集合をそのままC#、F#と書く 1行目から C# ∩ F# = φ 2行目から F# ⊆ C# ∴F# = φ アッー
182 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 01:45:50 ] aho
183 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 01:52:06 ] (C#でできることすべて)はF#でできない。 ではなく C#でできることにはF#でできないことがある。 という意味なのか
184 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 01:59:02 ] 仕様書でこういうどちらとも取れる言葉遣いをしていたら揉め事の種になるな
185 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 02:00:23 ] F#使ったことないけど、 C#では var f = i=>i で型推論が働かず、コンパイルが通らない。 F#ではできる!(=F#でしかできない事) という認識で良いでしょうか?
186 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 09:14:42 ] 開発はなに使ってますか?VS2008?
187 名前:名無しさん♯ mailto:sage [2007/11/30(金) 10:30:03 ] 気がつけば、F# 1.9.3.7にマイナーアップデート。 ttp://research.microsoft.com/research/downloads/Details/e8478d6b-49c0-4750-80eb-0e424d1631a3/Details.aspx そして待望のこれ。F#との相性よろし。(´ー`) ttp://www.microsoft.com/downloads/details.aspx?FamilyID=e848dc1d-5be3-4941-8705-024bc7f180ba&DisplayLang=en 改めてこちらにも注目。 ttp://research.microsoft.com/research/downloads/Details/f9d6994e-45f6-49b8-b3c9-2a44bb2a4c50/Details.aspx
188 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 10:50:05 ] C#で航海関数(なぜか変換できない)かけるのかとこ一時間
189 名前:デフォルトの名無しさん mailto:sage [2007/11/30(金) 10:58:20 ] ハァ?
190 名前:名無しさん♯ mailto:sage [2007/11/30(金) 18:05:31 ] System.Linq.ParallelEnumerable System.Linq.Parallel.Enumerable まぎらわしい・・・。(´・ω・`) 前者はIParallelEnumerable用、後者はIEnumerable用。
191 名前:名無しさん♯ mailto:sage [2007/11/30(金) 19:00:00 ] ParallelEnumerableに、ForAllなんていうAction系の拡張メソッドが。 オリジナルのEnumerableにもこれ付けてほしかったのに。(つД`)
192 名前:名無しさん♯ mailto:sage [2007/11/30(金) 19:36:06 ] Parallel.Aggregateはどこへ行った?と思ったら、 Parallel.For<TLocal> Parallel.ForEach<TSource, TLocal> がその代わりらしい。でも、使い方がちょっとわかりにくい・・・。(´・ω・`)
193 名前:名無しさん♯ mailto:sage [2007/11/30(金) 20:05:28 ] >>191 のForAllは、inverted enumerationというやつだった。 ForEachのつもりで使うと、順番がバラバラで困ったことになる。 MSDN Magazineできちんと解説してた内容をすっかり忘れてた・・・。orz ttp://msdn.microsoft.com/msdnmag/issues/07/10/PLINQ/default.aspx
194 名前:デフォルトの名無しさん [2007/11/30(金) 23:25:34 ] research.microsoft.com/research/downloads/Details/e8478d6b-49c0-4750-80eb-0e424d1631a3/Details.aspx www.microsoft.com/downloads/details.aspx?FamilyID=e848dc1d-5be3-4941-8705-024bc7f180ba&DisplayLang=en research.microsoft.com/research/downloads/Details/f9d6994e-45f6-49b8-b3c9-2a44bb2a4c50/Details.aspx
195 名前:名無しさん♯ mailto:sage [2007/12/01(土) 00:16:49 ] SEQUENTIAL_THRESHOLDがからむと、チューニング(値決め)がむずかしそうですのう。(´・ω・`)
196 名前:名無しさん♯ mailto:sage [2007/12/01(土) 13:20:31 ] TPLむずかし杉ワロタw #r "System.Core.dll"; #r "System.Threading.dll"; #light open System open System.Linq open System.Threading open Int32 let _ = let sum = ref (to_int64 0) do Parallel.For(0, 1000000, new Func<_>(fun _ -> !sum), new Action<_,ParallelState<_>>(fun i st -> st.ThreadLocalState <- st.ThreadLocalState + (to_int64 (i + 1))), new Action<_>(fun localSum -> Interlocked.Add (sum, localSum) |> ignore)) Console.WriteLine("TPL : {0}", !sum) let _ = let seq = ParallelEnumerable.Range(1, 1000000) ParallelEnumerable.Aggregate(seq, to_int64 0, new Func<_,_,_>(fun sum i -> sum + (to_int64 i))) |> fun sum -> Console.WriteLine("PLinq : {0}", sum)
197 名前:名無しさん♯ mailto:sage [2007/12/02(日) 01:01:31 ] dual coreでのパフォーマンスアップは1.5〜1.6倍といったところでしょうか。 quadで動かしてみたいのう。(´・ω・`)
198 名前:名無しさん♯ mailto:sage [2007/12/02(日) 23:54:31 ] F#じゃないけど、こんなのを取りまとめ中。 ttp://cid-c42499cb3a347006.skydrive.live.com/self.aspx/Public/LinqUtils.cs C#も十分関数的ですのう。(´・ω・`)
199 名前:デフォルトの名無しさん mailto:sage [2007/12/03(月) 03:17:53 ] なんかむずむずする関数名だな。
200 名前:デフォルトの名無しさん mailto:sage [2007/12/03(月) 04:41:19 ] >>198 ・Unitは確かにムズムズするな。unit 型と混乱しそう。 ・IsEmptyの実装は Enumerable.Count<T>使うより Enumerable.Any<T>使った方が良いんでは? Count使うと無限リストで死ねる。 てかAnyがあるからIsEmpty要らん気もするけど。個人的には。
201 名前:デフォルトの名無しさん mailto:sage [2007/12/03(月) 09:10:48 ] C#もラムダ式で再帰を書く方法の改善と末尾再帰の最適化をやってくれるようになったら 関数型っぽく遊べるようになるんだがな。
202 名前:デフォルトの名無しさん mailto:sage [2007/12/03(月) 09:14:32 ] その辺は棲み分けでしょ .net frameworkって糊を上手く使う所ってことで
203 名前:名無しさん♯ mailto:sage [2007/12/03(月) 10:49:17 ] >>200 コメント感謝です。 > ・Unitは確かにムズムズするな。unit 型と混乱しそう。 前は「Lift」って名前にしてたんですが、そっちの方がわかりやすいでしょうか? > ・IsEmptyの実装は Enumerable.Count<T>使うより > Enumerable.Any<T>使った方が良いんでは? Anyの使い方を知らなかっただけでつ。(´・ω:;.:... 勉強になりますのう。
204 名前:デフォルトの名無しさん mailto:sage [2007/12/03(月) 11:17:49 ] >>203 個人的にはLiftで良いと思う。 ただ、.NET全般として見たときには Nullableのところで"Lift"を使っちゃってて面倒鴨。 ttp://msdn2.microsoft.com/en-us/library/system.linq.expressions.unaryexpression.islifted(VS.90).aspx monadがあればこの辺のメタな名前の衝突は回避できるというか統合できるのかのぅ。
205 名前:名無しさん♯ mailto:sage [2007/12/03(月) 11:29:57 ] >>204 修正しますた。ついでに使用例も。( ゚д゚)ノ ttp://cid-c42499cb3a347006.skydrive.live.com/self.aspx/Public/LinqUtilsDemo.cs > monadがあればこの辺のメタな名前の衝突は回避できるというか統合できるのかのぅ。 monoid派が「Unit, Bindにすべし!」と言い出す悪寒・・・。
206 名前:名無しさん♯ mailto:sage [2007/12/03(月) 23:16:44 ] うーん、結局のところ かなり必要 → ZipWith できれば必要 → Lift (T -> IEnumerable<T> のインターフェイスで) ぐらいで、他は別にイラネって感じかもしれん・・・。(´・ω・`)
207 名前:名無しさん♯ mailto:sage [2007/12/03(月) 23:35:51 ] Cycleは漏れ的にはお気に入りだけど、実際には使わんよなあ・・・。(;´Д`)
208 名前:デフォルトの名無しさん mailto:sage [2007/12/04(火) 00:29:38 ] OCamlは糞言語だな。F#は大丈夫なんだろうな。
209 名前:名無しさん♯ mailto:sage [2007/12/04(火) 20:11:20 ] TPLは、TaskManagerPolicyを変えて、ParallelよりもConcurrentライブラリとして使えば便利かもしれん。 でもそれって何てjava.util.concurrent?(´・ω・`)
210 名前:デフォルトの名無しさん [2007/12/20(木) 02:46:46 ] Lisp系に比べるとML系って泥臭いというか、洗練されていない感じがする。頭悪そうな感じ。
211 名前:デフォルトの名無しさん mailto:sage [2007/12/21(金) 08:06:21 ] でも得てしてそういう言語の方が広まったりしない?
212 名前:デフォルトの名無しさん [2007/12/21(金) 08:42:24 ] MLは普及してないだろ。
213 名前:デフォルトの名無しさん mailto:sage [2007/12/21(金) 14:10:28 ] まさに目くそ鼻くそ
214 名前:デフォルトの名無しさん mailto:sage [2007/12/21(金) 14:41:19 ] MS は # シリーズが Z までいったら, 次は $ シリーズを展開してくれると期待している.
215 名前:デフォルトの名無しさん mailto:sage [2007/12/21(金) 23:44:56 ] M$
216 名前:デフォルトの名無しさん mailto:sage [2007/12/23(日) 23:59:49 ] >>210 CL, Scheme, SML, OCaml なんかを比べているのであれば、 どれも大差無い様に見えるけど。歴史的に一番泥臭いのは CL だろうけど…
217 名前:名無しさん♯ mailto:sage [2007/12/24(月) 10:52:24 ] Scalaの言語仕様もよくできてますなあ。 F#よりもHaskellに近い希ガス。 もしかしたら、C# 4.0のヒントもこの中にあるのかもしれん。(´・ω・`)
218 名前:デフォルトの名無しさん mailto:sage [2007/12/24(月) 11:24:46 ] 気になる開発プロダクツ 第7回 Scala 2.6.0-final gihyo.jp/dev/serial/01/awdp/0007 初めて名前聞いた. ところでみんな将来的には業務に使おうと思ってF#とか 関数型言語をいじってるの?
219 名前:デフォルトの名無しさん mailto:sage [2007/12/26(水) 03:54:29 ] Scala、Rubyみたいな言語だなw
220 名前:名無しさん♯ mailto:sage [2007/12/26(水) 11:42:54 ] 一部で話題になってる論文。 ttp://www.cs.kuleuven.be/~adriaan/?q=genericshk これをJVM上の言語で実現したのはすごいなあ。 一方、.NETの方では・・・。(´・ω・`) ttp://www.haskell.org/pipermail/glasgow-haskell-users/2005-January/007603.html
221 名前:名無しさん♯ mailto:sage [2007/12/26(水) 21:40:07 ] いちおう動いたけど、なんか間違えてるような・・・(´・ω・`)? trait Monad[M[_]] { def returnM[T](x: T): M[T] def bindM[T, U](m: M[T], f: T => M[U]): M[U] } abstract class Maybe[T] case class Just[T](x: T) extends Maybe[T] case class None[T] extends Maybe[T] object Test { implicit object MaybeMonad extends Monad[Maybe] { def returnM[T](x: T) = Just(x) def bindM[T, U](m: Maybe[T], f: T => Maybe[U]): Maybe[U] = m match { case Just(x) => f(x) case _ => None() } } def test[T, U](a: Maybe[T], f: T => U)(implicit m: Monad[Maybe]) { m.bindM(a, (b: T) => m.returnM(f(b))) match { case Just(x) => println(x) case _ => println("None") } } def main(args: Array[String]) { test(Just(100), (x: Int) => x + x) // 200 test(None(), (x: Int) => x + x) // None } } testの第1引数にMaybeを使ってしまうと、Monadで汎化した意味がないような・・・。
222 名前:名無しさん♯ mailto:sage [2007/12/26(水) 21:52:51 ] しかも、JustとNone。名前の由来が微妙に混ざってる・・・。orz
223 名前:名無しさん♯ mailto:sage [2007/12/26(水) 22:23:36 ] あ、こうすればいいのか。(゚∀゚) def test[M[_], T, U](a: M[T], f: T => U)(implicit m: Monad[M]) { m.bindM(a, (b: T) => m.returnM(f(b))) }
224 名前:名無しさん♯ mailto:sage [2007/12/26(水) 22:50:55 ] 関数を { 〜 } で囲むと戻り値はUnitになっちゃうのか・・・。なるほど。(;`・ω・)
225 名前:名無しさん♯ mailto:sage [2007/12/26(水) 23:11:49 ] 修正版でつ。 trait Monad[M[_]] { def returnM[T](x: T): M[T] def bindM[T, U](m: M[T], f: T => M[U]): M[U] } abstract class Maybe[T] case class Just[T](x: T) extends Maybe[T] case class Nothing[T] extends Maybe[T] object Test { implicit object MaybeMonad extends Monad[Maybe] { def returnM[T](x: T) = Just(x) def bindM[T, U](m: Maybe[T], f: T => Maybe[U]) = m match { case Just(x) => f(x) case _ => Nothing[U]() } } def test[M[_], T, U](x: M[T], f: T => U)(implicit m: Monad[M]) = m.bindM(x, (y: T) => m.returnM(f(y))) def main(args: Array[String]) { def p[T](m: Maybe[T]) = m match { case Just(x) => println(x) case _ => println("Nothing") } p(test[Maybe,Int,Int](Just(100), (x: Int) => x + x)) p(test[Maybe,Int,Int](Nothing(), (x: Int) => x + x)) } }
226 名前:デフォルトの名無しさん mailto:sage [2007/12/27(木) 14:09:13 ] 前、海外でF#使える人の求人あったけどどんなものなのかね? 日本でもかまわんけれど、実際のシステムで使われてるかなど教えてエロイ人
227 名前:デフォルトの名無しさん mailto:sage [2007/12/29(土) 14:46:20 ] >>226 実際は雑用とかだろ
228 名前:デフォルトの名無しさん mailto:sage [2007/12/29(土) 14:59:22 ] このスレ一人しかいないのか知らんけど、過疎ってるからってさすがにつっこむべきかと・・・・ そのコードF#ですか? >>226 基本的には.netアプリだけど、ASP.NETでスクリプト的に使うんだろうな〜 まあIronPythonもそうだがちゃんとしたフォームデザイナがないとGUIアプリは作りづらいし 当然C#とかVBを置き換わるものではない ってか常識で考えろ
229 名前:デフォルトの名無しさん mailto:sage [2007/12/29(土) 23:12:31 ] >>228 常識が何をさしてるのか知らんが、別に既存の業務土方アプリ作るのにF#使うことは無いでしょう。 まぁF#のほうが生産性高いとは思うけれど、メンテや技術者の人数から見ても選択されることはないかと。 それよりも自分が見たのは、何かの科学計算に向けての実験的なアプリの作成などに絡む部門だったような。Lispとかの経験でも可とかいってたから何か面白そうなにおいがした。
230 名前:名無しさん♯ mailto:sage [2008/01/04(金) 22:35:35 ] Scalaをいろいろと触ってみましたけど、オブジェクトの発想が強すぎて 関数型としては扱いづらいですね・・・。(´・ω・`) F#の比較対象としては不向きかも。
231 名前:名無しさん♯ mailto:sage [2008/01/06(日) 21:44:12 ] fsi --quiet --exec hoge.fs hoge.fsを実行してそのまま終了。 今までこのオプションを知らんかった・・・。orz そうなると、DLRの使い道が一気に減ってしまうがな。(´・ω・`)
232 名前:デフォルトの名無しさん [2008/01/19(土) 17:56:27 ] F# 1.9.3.14あげ
233 名前:デフォルトの名無しさん mailto:sage [2008/02/02(土) 08:32:45 ] ttp://www.iunknown.com/2008/02/langnet-wrap-up.html IronRubyの中の人による、Lang.NETのまとめ へじたんのお言葉 I think that the taxonomies of programming languages are breaking down. I think that languages are fast becoming amalgam. ... I think that in 10 years, there won't be any way to categorize languages as dynamic, static, procedural, object, and so on. だそうで。 F#の学習はいい先行投資かもしれないねぇ。まぁ楽しいからやってるんですし、皆さんそうなんでしょうけど。
234 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 00:18:28 ] どうせ次のC#までまた2年ぐらいあるんだろうしなぁ・・・ F#製品に使うことにするノシ
235 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 16:13:36 ] OCamlとか知らんでいきなり#lightでやるの危険だな letに宣言と式があるなんて知らんかったし、do,doneとかもかなり混乱する Web上だとそういう初歩の情報ないし。 OCaml入門は読むべしだ。互換性とか適当だけど。 Expert F#は割とわかりやすかった
236 名前:デフォルトの名無しさん mailto:age [2008/02/08(金) 00:45:43 ] ひゃー
237 名前:デフォルトの名無しさん [2008/02/08(金) 00:49:55 ] F#の日本語本うp
238 名前:名無しさん♯ mailto:sage [2008/02/24(日) 01:19:50 ] F#でMapReduceもどきを作ってみますた。(「もどき」なのは、sequentialにしか動かないから。w) C# LINQに比べると、やっぱり圧倒的に記述しやすいわ。 #light open System open Seq let ap_snd f (a, b) = (a, f b) // MapReduce let map_reduce m r = map_concat m >> groupBy fst >> orderBy fst >> map (ap_snd (map snd) >> r)
239 名前:名無しさん♯ mailto:sage [2008/02/24(日) 01:20:36 ] // word count demo let mapper (_, v : string) = v.Split [| ' '; ','; '.'; '!' |] |> filter (not << String.IsNullOrEmpty) |> map (fun s -> (s.ToLower(), 1)) let reducer = ap_snd (fold1 (+)) let data = [ "This is a pen."; "Hello, World!"; "All your base are belong to us."; "My name is nanashi." ] let _ = mapi (fun i s -> (i, s)) data |> map_reduce mapper reducer |> iter (fun (k, v) -> Console.WriteLine("{0}\t{1}", k, v))
240 名前:名無しさん♯ mailto:sage [2008/02/24(日) 12:44:20 ] C#版も置いておきまつ。クエリーの部分だけはきれいなんですが・・・。(´・ω・`) using System; using System.Collections.Generic; using System.Linq; // MapReduce public interface IMapper<K1, V1, K2, V2> { IEnumerable<KeyValuePair<K2, V2>> Map(KeyValuePair<K1, V1> p); } public interface IReducer<K2, V2, K3, V3> { KeyValuePair<K3, V3> Reduce(KeyValuePair<K2, IEnumerable<V2>> p); } public class MapReduceJob<K1, V1, K2, V2, K3, V3> { Func<KeyValuePair<K1, V1>, IEnumerable<KeyValuePair<K2, V2>>> mapper; Func<KeyValuePair<K2, IEnumerable<V2>>, KeyValuePair<K3, V3>> reducer; public MapReduceJob(IMapper<K1, V1, K2, V2> mapper, IReducer<K2, V2, K3, V3> reducer) { this.mapper = mapper.Map; this.reducer = reducer.Reduce; }
241 名前:名無しさん♯ mailto:sage [2008/02/24(日) 12:55:01 ] あれ?数分間書き込めなかった・・・。(´・ω・`) public IEnumerable<KeyValuePair<K3, V3>> Execute(IEnumerable<KeyValuePair<K1, V1>> data) { return from d in data from p in mapper(d) group p.Value by p.Key into g orderby g.Key select reducer(new KeyValuePair<K2, IEnumerable<V2>>(g.Key, g)); } } // word count class WCMapper : IMapper<int, string, string, int> { public IEnumerable<KeyValuePair<string, int>> Map(KeyValuePair<int, string> p) { return from s in p.Value.Split(' ', ',', '.', '!') where !String.IsNullOrEmpty(s) select new KeyValuePair<string, int>(s.ToLower(), 1); } } class WCReducer : IReducer<string, int, string, int> { public KeyValuePair<string, int> Reduce(KeyValuePair<string, IEnumerable<int>> p) { return new KeyValuePair<string, int>(p.Key, p.Value.Sum()); } }
242 名前:名無しさん♯ mailto:sage [2008/02/24(日) 12:55:35 ] static class Test { static string[] data = { "This is a pen.", "Hello, World!", "All your base are belong to us.", "My name is nanashi." }; static void Main() { var d = data.Select((s, i) => new KeyValuePair<int, string>(i, s)); var job = new MapReduceJob<int, string, string, int, string, int>(new WCMapper(), new WCReducer()); foreach (var p in job.Execute(d)) { Console.WriteLine("{0}\t{1}", p.Key, p.Value); } } }
243 名前:名無しさん♯ mailto:sage [2008/02/24(日) 13:37:52 ] Map/Reduce = Select/Aggregate だと今まで勘違いしてたけど、 Map -> SelectじゃなくてSelectMany(generator的な操作) Reduce -> 確かにAggregateの操作だけど、厳密にはSelectの中で(selectorとして)実行されるAggregate だったのね。実際に書いてみないとなかなか気づけんわ。(´・ω・`)
244 名前:名無しさん♯ mailto:sage [2008/02/24(日) 13:48:26 ] ついでにネタ振り。 末尾再帰のスタイルはどちらがお好み? #light // val sum : int list -> int let sum1 l = let rec sum' l v = match l with | [] -> v | h::t -> sum' t (v + h) sum' l 0 let sum2 = let rec sum' v = function | [] -> v | h::t -> sum' (v + h) t sum' 0 要は、sum' の引数の順番の問題なのですが・・・。
245 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:32:14 ] 僕は末尾再帰用の追加の引数は最後に置くなぁ もともと引数は「入力、出力」の順で書いてたので。 末尾再帰は局所定義にすることがほとんどで 部分適用をしないから、それでもいいかなと。
246 名前:名無しさん♯ mailto:sage [2008/02/24(日) 16:11:10 ] おお、即日レスがつくとは・・・。(つД`) >>245 > もともと引数は「入力、出力」の順で書いてたので。 確かにそうですね・・・。 sum2の方は一見ムダがないですけど、意味的にはちょっと無理やりなのかもしれませんね・・・。(´・ω・`)
247 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 19:26:50 ] F#がNTPに対応すれば問題なし。
248 名前:名無しさん♯ mailto:sage [2008/02/25(月) 14:49:13 ] Haskellにも移植してみますた。 import Data.Char import Data.List hiding (groupBy) -- MapReduce mapReduce :: (Ord k) => (a -> [(k, v)]) -> ((k, [v]) -> b) -> [a] -> [b] mapReduce m r = map r . orderBy fst . groupBy fst snd . concatMap m -- word count mapper :: (Int, String) -> [(String, Int)] mapper (_, v) = map (\s -> (map toLower s, 1)) . filter (not . null) $ split " ,.!?" v reducer :: (String, [Int]) -> (String, Int) reducer (k, v) = (k, sum v) -- test data_ = [ "What is this?", "This is a pen.", "Hello, World!", "All your base are belong to us" ] main = mapM_ p $ mapReduce mapper reducer $ zip (iterate (+1) 0) data_ where p (k, v) = putStrLn $ show k ++ "\t" ++ show v
249 名前:名無しさん♯ mailto:sage [2008/02/25(月) 14:50:11 ] -- utils orderBy :: (Ord k) => (a -> k) -> [a] -> [a] orderBy fk = sortBy (\x y -> fk x `compare` fk y) groupBy :: (Eq k) => (a -> k) -> (a -> v) -> [a] -> [(k, [v])] groupBy _ _ [] = [] groupBy fk fv l = let key = fk $ head l in let (g, rest) = partition (\x -> fk x == key) l in (key, map fv g) : groupBy fk fv rest split :: [Char] -> String -> [String] split sep s = case break (\c -> any (==c) sep) s of (v, []) -> [v] (v, h:t) -> v : split sep t
250 名前:名無しさん♯ mailto:sage [2008/02/25(月) 14:52:45 ] こうやって見ると、F#は.NETの資産を使える分、すごく楽だなあ・・・。(´・ω・`)
251 名前:名無しさん♯ mailto:sage [2008/02/25(月) 20:37:46 ] こだわる人はこだわる修正でつ。(´・ω・`) mapper :: (Int, String) -> [(String, Int)] mapper = map (\s -> (map toLower s, 1)) . filter (not . null) . split " ,.!?" . snd