【.NET】F#について語れ2【OCAML】
■ このスレッドは過去ログ倉庫に格納されています
MSResearchから出てきた.NETで使える関数型言語のひとつF# OCAMLの流れを汲むこの言語、いろいろと面白そうなことができそう。 そろそろ日本語の情報が充実してきそうなこの言語について、幅広く語れ。 http://www.fsharp.net/ 前スレ 【.NET】F#について語れ【OCAML】 http://hibari.2ch.net/test/read.cgi/tech/1186030985/ 関連スレなどは >>2- F#の未来はわからないがMLの流れは絶えることはない >>739 このサイトには誤訳があるので注意してね 間違いの無い記事は少ない 間違いを見つけ乍ら読むのがリテラシー discriminated unionも次々に採用されてるな やれやれ .netにバインドするライブラリってのは たとえばデリゲートをどうすんのかとか 属性どうするのかとかですぐつまづいてしまう JScript.NETやIronPythonがまさにそうだ F#はそのへん良く頑張ってるな F#というより.netの使い方の勉強に時間取られてなんだかね 質問させてください F#をC#と併せて勉強中です。C#の場合、高階関数に渡すラムダ式の中で 以下のように配列のインデックスを使えるのですが、F#だとどう書けばよいか分かりません F#のラムダ式中で配列のインデックスを使う方法があればお教え願います (C#) var array1 = new[] { 12, 33, 46, 8, 23, 42, 41}; var array2 = array1.Where((x, index) => index % 2 == 0).ToArray(); // array1の偶数番目のみの配列を新たにつくる (F#) let array2 = Array.filter (fun x index -> index % 2 = 0) array1 // こうはできない ちょっと長ったらしくて、もっとスマートなやり方があるかもしれんが とりあえずは、こうすればできる Array.mapi (fun index x -> (index, x)) array1 |> Array.filter (fun (index, x) -> index % 2 = 0) |> Array.map (fun (index, x) -> x) >>748 なるほど、mapiだとインデックスが使えるんですね そこで一旦indexを要素にもったタプルの配列をつくると 勉強になりました >>750-751 ありがとうございます スマートに書けるようになりました Array.indexed array1 |> Array.choose (fun (index, x) -> if index % 2 = 0 then Some x else None) >>753 わざわざありがとうございます こういうyieldを使った書き方はまだ詳しく勉強してないんですが、 こっちだと中間のデータをつくらないんでパフォーマンスがよさそうですね 勉強して試してみます F#って普通に個人で趣味アプリ作ったりする場合でもC#と比べて恩恵感じられる? 関数型って算術演算や金融関係で威力を発揮するけどそれ以外だと却って手間が増えるだけみたいなイメージある >>755 C#に比べてVSのサポートがイマイチって所が多々あるけれど、それを補ってかつはるかに上回るメリット得られるお。 正直C#でなんかサポートが足りない所、たとえばUI周りとか以外で使いたくないしF#使える所は全部F#で書いてる。 F#はバージョンが5つぐらい進んだC#と捉えるのが正しいと思う >>757 そんなにすごいのか 興味あったし頑張って勉強してみるよ >>760 やってみて損はないと思いますー 実案件で使えなくても考え方学ぶことでC#での書き方も良くなると思うし、実案件でも人の問題とかなければ使える場面は多々あると思う。 勉強し始めたけど、いつなくなるのか心配 MSって、切るときはバッサリ行くよな F#デビューしようと思って本探してるんだがC#er向けの本ってないのな ググるとサイトはいっぱい出てくるけど こういう場合は関数型言語について書かれた本をとりあえず買っとけばいいのかな Real World Functional Programming: With Examples in F# and C# かな。たしか英語の原書しかないけど でもまずプログラミングF#読んだ方がいいと思う 俺は実践F#関数型プログラミング入門って本で勉強したけど、なかなか良い本だったよ 書き方が平易な感じでサクサク進められて、基礎的な部分は一通りキッチリ習得できたと思う 勉強中で悪いんだけど 実践F#関数型プログラミング入門は確かにとっつきやすいんだけど 説明不足と思われるところが散見されるように思う かといってプログラミングF#で十分ってわけではないんだけど 例えば、今アクティブパターン見てるんだけど、いまいち動作がわかんねー 分類としての役割と、型変換の役割があるみたいだけど、 その内部動作っというか、統一的にどのように動作してるのかがわからん 実装は関数呼び出しの条件一致だろうけど、使うぶんにはそのパターンになるかどうかって感じでよくないか? パラメータわたしのやつは順序がおかしくて分かりづらいと思うが >>766 俺もその本で関数型学んだ モッナードとかは無いけどオブジェ脳の人が感触をつかむのには良いよね >>769 以下の=ソース=において、 | FIleExtension ".jpg"はどう動作すると考える? プログラミングF#には記述があるからわかるけど 普通に ".jpg"はFIleExtensionの引数にしか見えない 疑問点1 match式の|の後はパターンの記述だけど、関数呼び出しの場合の約束事が不明 疑問点2 | FIleExtension ext は.jpgの方とほぼ同じ記述だけど、こちらは代入 さしあたって、切り分けできるのかな? 出来たとしても、わかりずらいし。 =========== ソース ============ let (|FIleExtension|) filepath=Path.GetExtension(filePath) let determinFIleType(filepath :string) match filepath with | FIleExtension ".jpg"->printfn "画像" | FIleExtension ext->printfn "未知 [%s]" ext あれ?空白が無視されてるな match式以降はブロック別で、ずれてますので、 まぁわかりますよね |の後は元の値がこのパターンに合うか?って感じの比較対象が来るのでFileExtension ".jpg"と言う値って感じに掴んでる。 正規表現の奴はそのregexを元にほにゃららを返す値って感じ。 けどほんとはパターンを区別するって言うセレクターとした方がいいのかな? たぶん違う | FIleExtension ".jpg"->printfn "画像"の方は、 FIleExtensionの引数がfilepathで、その結果が".jpg"とマッチするかどうか | FIleExtension ext->printfn "未知 [%s]" extの方は FIleExtensionの引数がfilepathで、その結果をextに代入(let束縛?) って、ことみたい(プログラミングF#に記述の例で上のように解釈するような説明あり) 実践F#にも同様な例(P295)はあるけど、こちらは、説明なし いや俺はそう言う風な理解をしてるって話なんだが。 実体は上から順番に関数呼び出しの条件マッチだと思うが動作の仕組みを知りたいんだったらILを見れば。 >ILを見れば。 たしかにね。いままで避けてきたから、考え付かなかった。 ただ、実践F#の方はなんの説明もないんだよ それで理解できるわけないってーの (| FIleExtension ".jpg" なら、FileExtensionの引数は”.jpg”でその結果が、filepathとマッチが 普通の理解だと思う) 多分、F#の文法理解のキモは、実践F#のどっかに書かれてた、 ”let束縛や関数束縛にはパターンマッチが宿る”ってのがあって それは何ぞやってことかなとも思うんだけど やってる人いるっぽいけど、興味あるので是非人柱って欲しい Xamarinでも使えると聞きたけど、実際に実用に耐えるレベルで使える感じ? それともまだちょいきびしい? >>763 バージョンが5つぐらい進んだC# くらい凄いのがなくなるわけ無いじゃん >>777 >>779 勘違いしちゃいけないのは 成長中とかじゃなくてとっくに成熟してる分野だからな 一部の人が持ち上げてるだけで一般的にはそうでもないだけ >>755 関数型って算術演算や金融関係で威力を発揮する という理屈を解説してくれ >>779 使えるし実案件で使ってる。 全部F#とかはやりにくいところもあると思うけど可能。 ロジックをF#でとかは普通に可能。 ただしDLLの参照はプロジェクトファイル直で編集しないとダメかも f#はmonoで動くように作ってるので問題無いが、 あとはC#と同じくiosの制限に引っかからないかぐらいかな。 動的コード減らすように、ios向けにコンパイラ改良してるみたいではあるが。 sprintfの引数5個以上にすると実機ですっ飛ぶけど後は何も問題になってない 軽量構文では前方参照できてもよくない? というか前方参照できないのがVSに統合してるのに広がらない大きな理由のような >>788 そんな理由でF#使うのやめるような奴いねーよ immutableでもちゃんと書けるんだすごーい→しばらくして 現実に引き戻されちゃうold Cですら前方宣言あったよね?と むしろ適度に参照制限されてた方がいい。ミュータブルよりイミュータブルが利点を持つのと一緒 (O抜きの)CAML当時のPCでは関数型言語のコンパイラで前方参照なんてやってたら まるで使い物にならなかっただけの流れだとなんとなく思う 前方参照やりだすと型推論が面倒くさいことになりそうな気がする トップレベルの定義は型注釈必須になっちゃったりするんじゃね F# 4.1 未満でも↓のように関数の前方参照ができるし、前方参照に比べて余分な型注釈が必要になることもない let rec f1 () = f2 "" + f3 1 and f2 s = s.Length and f3 x = x むしろ f2 のように型推論が強化される場合もある 多分、今話題に上がってる前方参照って、同一のlet式内って狭い範囲の話じゃないと思うよ・・・ 前方参照できないとトップダウンでは書けないよね 上から下にいくにつれて詳細化するほうが読みやすい 上から下にかけて詳細化って何。 インターフェース定義とその具体的実装的なことでも言ってんの? >>802 わからんいうてる奴に「わかるよ!」ってなんやねん ガイジか死ね氏ねウンコアヘアヘ仮面 Microsoft、「F# 4.1」と「Visual F# Tools for Visual Studio 2017」を発表 http://forest.watch.impress.co.jp/docs/news/1048457.html 研究所に担当者が興味持っている間は続くんじゃないかな。 Open EditionのREADMEには、F# Core Engineering Groupって書いてあったけど、どこの組織かはよく分からない。 https://github.com/fsharp/fsharp/blob/master/README.md#maintainers >>804 数ヶ月書き込みがない過疎スレで「いつものあれ」とか無理あるだろ あらクソスレにずっといついてるいつものあれでしたか 質問です let add x y = x+y を用いた関数合成した場合 ■関数定義成功 1.let ft = add 10>> add ■関数定義失敗 2.let ft = add >> add 3.let ft = add >> add 10 2.、3.が失敗する理由は何でしょうか? FSharpFuncが+演算子のオーバーロードを持ってないからだろ >>812 let add x y = x+y を let add x y = 0 にしてみたんだけど、やっぱだめでした。 エラーは以下。 エラーの見方がよくわかんないんですけど、 これ見ると、>>の左側のaddは一引数を求めると考えていいんですよね? > let test = add>>add;; let test = add>>add;; ----------------^^^ stdin(13,17): error FS0001: 型が一致しません。 '(int -> int) -> 'a' という指定が必要ですが、 'int -> int -> int' が指定されました。型 'int -> int' は型 'int' と一致しません >> オペレータのシグネチャ見てみ。 >>は('a->'b)->('b->'c)->('a->'c)となってる。つまり('a->'b)の関数と('b->'c)の関数を受け取って('a->'c)を返す。 ここでaddを見るとint->int->intなのでこれはまたint->(int->int)でもある。 つまりintを受け取ってint->intを返す。 ここで'a->'bに当てはめると'aがint、'bがint->intとなる。 そうすると>>の右の値は(int->int)->'cでなければならない。 けれどaddを渡していてそれはint->int->intであって(int->int)->intではない。 >>814 Thx 大枠理解しました。 >ここでaddを見るとint->int->intなのでこれはまたint->(int->int)でもある。 特にこの見方は非常に参考になります。 多分今回の件きちんと理解すると、 自分の中でごっちゃになってる部分が結構すっきりすると思います ここから先は、調べてみます ありがとうございました X Y Z Nとスペースで区切られた文字列が標準入力から入力された時、 Console.ReadLine().Split [|' '|]を、一つのletでint X Y Z Nそれぞれに入れるのには どうしたらいいでしょうか? >>816 let [|X;Y;Z;N|]=... >>819 ありがとうございます。 それ前に一回試してみてて、「試してみたけどマッチ不完全って出てムリでしたよ」書こうとして、 もう一回試してみたら、ちゃんとコンパイルできました。 何を言っているかわからないと思いますが、エラーは他の所だったんだなぁと。 >>820 ワーニングは出るけどコンパイルは出来るはず。 それもエラーになるような設定ってできるのかな。 けどおかしな文字列与えたら実行時にすっ飛ぶから、ほんとはlet じゃなくmatch使うべき。 >>822 match憶えました。 >>821 PAIZAのPOH7でF#が使えるのでやってみました。F#歴3日くらいです。 とりあえず全部解けたけど、ちゃんとした本を読んだ方がいいんだろうなぁ…… あの程度の炎上でサービス使えなくなってたらなんも使えんで アレは炎上大好き民族のはてな民のデイリーノルマみたいなもんや PAIZAすることなくなったので、HackerrankのDashboardで修行することにしました。 AtCoderやyukicoderでも良さそうけどな 競プロするなら競プロスレあるぞ 競技プログラミングにハマるプログラマのスレ 9 [無断転載禁止]c2ch.net https://tamae.2ch.net/test/read.cgi/prog/1493085730/l50 match Array.countBy (fun x -> x = i + 1) array with | [|(false, f); (true, t)|] -> t | [|(true, t); (false,f)|] -> t | [|(true,t)|] -> t | [|(false,f)|] -> 0 というのは正しいのですか?ケースが増えるにしたがって、めっちゃ増えちゃう気がするんだけど、 ループとか関数で処理することはできないんでしょうか。 >>829 マッチ式の練習って意味ならこうかな match Array.countBy (fun x -> x = i + 1) array with | [| _ ; (true, count)|] | [| (true, count) ; _ |] -> count | _ -> 0 関数で探すならこんな感じか array |> Array.countBy (fun x -> x = i + 1) |> Array.find (fun (x, count) -> x = true) |> snd 単に条件マッチする要素数を数えたいだけなら Array.filter(fun x -> x = i + 1) array |> Array.length またはこう書いたり Array.sumBy (fun x -> if x = i + 1 then 1 else 0) array 自分も勉強中だからもっといい書き方があるかもしれない >>830 >>831 ありがとうございます。 ワイルドカードを使う、関数でフィルターする、ラムダ式を工夫する、どれも参考になります。 10日くらいやって、F#を本格的にやる覚悟ができてきたので本予約してきました。 でもまだ、典型的なループにbreakがないのには慣れないなー…… ループで分岐を行うという事に疑問を抱くところまで洗脳しましょう 世界トップクラスのプログラマだけど質問ある? まあねーかw 最近の日本人はたるんでねーか? まあこんなしょぼいところに俺レベルのプログラマなんているわけねーよなwwwwwwww ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.0 2024/04/24 Walang Kapalit ★ | Donguri System Team 5ちゃんねる