【激突】関数型言語 VS オブジェクト指向言語2
■ このスレッドは過去ログ倉庫に格納されています
0001営利利用に関するLR審議中@詳細は自治スレへ
2012/04/07(土) 21:26:47.61一部には関数型言語を崇拝している人もいます
どちらが上なのか、この際はっきりさせましょう
前スレ http://toro.2ch.net/test/read.cgi/tech/1331328955/
0217デフォルトの名無しさん
2012/04/12(木) 03:42:11.670218デフォルトの名無しさん
2012/04/12(木) 06:22:33.36それが他に漏れてないことを静的型検査できるのがメリット
静的型検査なんて要らないし、副作用の有無なんて
コメントにでも書いとけば分かるだろ
というプログラマにはメリット無い(批判する意図はないので注意)
0219デフォルトの名無しさん
2012/04/12(木) 06:34:07.76関数型言語のメリットでは無い
0220デフォルトの名無しさん
2012/04/12(木) 06:44:16.58TIOBEとか見て一喜一憂してるの?
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
JavaプログラマならJavaの人気が長期的に下がり続けてる
(ついに今月は2位に陥落)の見てショック受けてるの?
幾らでも他と交換可能な木っ端プログラマは大変だね
0221デフォルトの名無しさん
2012/04/12(木) 09:49:24.36普及率は人気の度合い。なぜ人気があるのか考える必要がある。
誰かさんの思い込みより価値ある。
0222デフォルトの名無しさん
2012/04/12(木) 09:50:24.09仮にIOを禁止しても、IOと殆ど同じモナドを簡単に作れる
だから禁止していいんだという解釈もあるが、禁止しても無意味だという解釈もある
Haskellが、いずれかの解釈を一方的にサポートすることはない
あくまで中立
0223デフォルトの名無しさん
2012/04/12(木) 09:55:43.85ソフトウェア工学上で問題になる事項をすべて解消しているわけではいないと思うんだけど
どう思う?
0224デフォルトの名無しさん
2012/04/12(木) 11:16:27.370225デフォルトの名無しさん
2012/04/12(木) 16:43:59.37全くもってその通り!!
中国語だって世界中で大人気だからな!!
0226デフォルトの名無しさん
2012/04/12(木) 16:51:24.45現実のコンピュータが副作用必須の設計で、モナドは副作用解決に使えるというだけ。
モナドが副作用解決のために作られた訳じゃない。
0227デフォルトの名無しさん
2012/04/12(木) 17:45:50.950228デフォルトの名無しさん
2012/04/12(木) 18:33:25.41らの提案したフレーム問題と区別して一般化フレーム問題と呼ばれている。
ソースはwikipedia
>>223
限定的なフレームを選択しないと、フレーム問題に対処できない
0229デフォルトの名無しさん
2012/04/12(木) 19:54:30.42対して従来のやり方は問題を死滅させず適宜再生産もする
農耕・牧畜をおぼえた文明人の手法
0230デフォルトの名無しさん
2012/04/12(木) 20:03:40.16単に生産性が低いものを賞賛してるだけのバカですねw
0231デフォルトの名無しさん
2012/04/12(木) 20:11:16.33・プロジェクトが成功した場合 => 成功したのはOOのおかげ
・プロジェクトが失敗した場合 => 設計者やプログラマがOOに未熟だった
以上の詭弁により、OOはソフトウェア工学の全ての問題を解決した
0232デフォルトの名無しさん
2012/04/12(木) 20:12:09.570233デフォルトの名無しさん
2012/04/12(木) 20:15:51.900234デフォルトの名無しさん
2012/04/12(木) 20:41:17.180235デフォルトの名無しさん
2012/04/12(木) 22:36:25.45生産性については職業プログラマの人に比較して貰うとして、少なくとも、rubyで入門書のサンプル以上のものが作れなかった自分が、haskellでは>>41,>>74のコードを書ける様になった
初心者には、rubyよりhaskellの方が自力でコード書ける様になり易いんじゃ無いかと思う
0236デフォルトの名無しさん
2012/04/12(木) 23:36:58.60数十ファイルからなるアプリを作ってから
書けるようになったといって下さい。
短い関数一つと程度、
あんなの誤差でしかない。
0237デフォルトの名無しさん
2012/04/12(木) 23:59:11.360238デフォルトの名無しさん
2012/04/13(金) 00:07:17.03EC-CUBE 4万行らしいよ。
0239デフォルトの名無しさん
2012/04/13(金) 00:08:42.48Rubyは10万行
0240デフォルトの名無しさん
2012/04/13(金) 00:12:30.38OpenPNE2 13万行
Linuxは1500万行らしい
http://www.infoq.com/jp/news/2012/03/Defects-Open-Source-Commercial
解析対象のオープンソースプロジェクトは、コード行数が10万〜50万のものが
ほとんど(700万行を超えるプロジェクトが2つ)で、
の合計コード行数は3,744万6,469行、平均コード行数は83万2,000行になった。
0241デフォルトの名無しさん
2012/04/13(金) 00:21:31.21gccが少し前は30~40万行あった、いまの4.6,47はもっとだろうな
0242デフォルトの名無しさん
2012/04/13(金) 00:23:31.62書きたいものを書ける様になったら行数関係無い気がするけど・・・
そもそも、私の場合、Rubyではどう書けばいいかすら思い浮かばない
(学習が足りないと言われればそうだけど、どっちも入門書読みかけ状態での知識でしかない)
Haskellは入門書読みかけの状態でも結構色々書けるから、入門者のモチベーション維持にも良いんじゃないかな
(少なくとも、自分のモチベーション維持には良い効果がある)
0243デフォルトの名無しさん
2012/04/13(金) 00:27:01.11プロである以上最低限のことです。
0244デフォルトの名無しさん
2012/04/13(金) 00:27:48.64間違えた、The compiler includes an IDE (Win32 only, sorry), CORBA, OLE, all in all 850000 lines of code. This is (nearly) all Dylan code.
0245デフォルトの名無しさん
2012/04/13(金) 00:33:06.76書きたくない物でも金を受けとる以上書き上げるのが…(ry
0246デフォルトの名無しさん
2012/04/13(金) 00:36:02.31あんたプロや。プログラマー(ry)や。
0247デフォルトの名無しさん
2012/04/13(金) 00:38:56.24プロじゃないと言うか、プロの卵として就職して半年で諦めたんですが・・・
そんな奴が、Haskellでなら、ちょっとは書ける様になったですよ
それで気付いたのは、やってる事はどの言語も同じなのかもなぁー・・・と
で、関数型言語はそのやってる事は同じ。の部分を気付きやすい言語だな・・・・と
他の言語で何やってるのか分かんなくて挫折した人は、一度、関数型言語に挑戦してみてほしいかも
0248デフォルトの名無しさん
2012/04/13(金) 00:46:28.21うん。やる気マンマンです。
0249デフォルトの名無しさん
2012/04/13(金) 01:27:06.58一緒に頑張りまっしい
多分、私はそもそものググルための用語を知らないのが、そもそもの才能の無さな気がする
なので、そもそもググらず自分で作っちゃえ!派な自分には関数型言語の方が性に合うっぽい
(不器用なのは自覚してる)
0250デフォルトの名無しさん
2012/04/13(金) 01:30:15.85作らずに言語を使ってるだけのくせに
0251デフォルトの名無しさん
2012/04/13(金) 01:41:31.45> なので、そもそもググらず自分で作っちゃえ!派な自分には関数型言語の方が性に合うっぽい
初心者なら当然のことだよ。
俺なんかだと、見ただけで簡単な処理と分かるようなもの、
自分で作れると分かっているものは、作っても時間
を浪費するだけで何の経験値にならないし、自慢にもならない。
でも初心者にとっては、そんなものでも
挑戦する価値がある課題なのだから。
自分で作ったんだって自慢げになるでしょ?
0252デフォルトの名無しさん
2012/04/13(金) 06:51:30.77ドカタ仕事で書くコードなんてAPI呼び出すだけ、コピペコード満載の
頭悪いコードなんだから
疑うなら適当なコード書く御題出してみ?Javaのコードとか出てこないから
0253252
2012/04/13(金) 06:57:36.95とかその手の言い訳を、御題のコードの10倍くらいの長さの文章で
必死に語ってくれるよ
本当は2chのレスに収まる規模のコードも書けないんだけどね
0254デフォルトの名無しさん
2012/04/13(金) 07:16:26.24じゃあお題。
プログラマーなら「FizzBuzz問題」解けるよな?
http://kohada.2ch.net/test/read.cgi/prog/1209467166/401
401 :仕様書無しさん:2012/04/09(月) 23:59:48.08
FizzBuzzクイズ
1.fizz.buzz #=> 1
3.fizz.buzz #=> "Fizz"
5.fizz.buzz #=> "Buzz"
15.fizz.buzz #=> "FizzBuzz"
となるようなメソッドfizz、buzzは定義可能か?
可能である場合、同様にgizzを追加定義し、
7.fizz.buzz.gizz #=> "Gizz"
21.fizz.buzz.gizz #=> "FizzGizz"
35.fizz.buzz.gizz #=> "BuzzGizz"
105.fizz.buzz.gizz #=> "FizzBuzzGizz"
105.fizz.gizz.buzz #=> "FizzGizzBuzz" と拡張・応用ができるか?
メソッドのコールに()が必須の言語では 3.fizz().buzz() 形式でも構わない。
オープンクラス機構やメソッドのない言語では関数(buzz(fizz(3)) #=> "Fizz" など)で。
0255デフォルトの名無しさん
2012/04/13(金) 07:48:45.37ありがとうです
では、仕事があるので明日私は書くと思いますが(飲んで帰るので、今日は無理)
ファイルと検索したい文字列をコマンドから入れて、見つかった行と列のリストを表示すると言うのはどうでしょう?
0256デフォルトの名無しさん
2012/04/13(金) 08:18:23.98$ cat fizzbuzz.hs
import Control.Monad (mapM_)
main = mapM_ (runFizzBuzz . gizz . buzz . fizz) [1, 3, 5, 7, 15, 21, 35, 105]
runFizzBuzz (n, s)
| s == "" = putStrLn $ show n
| otherwise = putStrLn $ show s
fizz n
| n `mod` 3 == 0 = (n, "Fizz")
| otherwise = (n, "")
buzz (n, s)
| n `mod` 5 == 0 = (n, showString s "Buzz")
| otherwise = (n, s)
gizz (n, s)
| n `mod` 7 == 0 = (n, showString s "Gizz")
| otherwise = (n, s)
$ runghc fizzbuzz.hs
1
"Fizz"
"Buzz"
"Gizz"
"FizzBuzz"
"FizzGizz"
"BuzzGizz"
"FizzBuzzGizz"
0257デフォルトの名無しさん
2012/04/13(金) 08:45:35.77map (gizz . buzz . fizz) [1, 3, 5, 7, 15, 21, 35, 105]
-- [1, "FIzz", "Buzz", "Gizz", "FizzBuzz", "FizzGizz", "BuzzGizz", "FizzBuzzGizz"]
map (buzz . gizz . fizz) [1, 3, 5, 7, 15, 21, 35, 105]
-- [1, "FIzz", "Buzz", "Gizz", "FizzBuzz", "FizzGizz", "GizzBuzz", "FizzGizzBuzz"]
0258デフォルトの名無しさん
2012/04/13(金) 08:54:17.090259デフォルトの名無しさん
2012/04/13(金) 09:05:31.58struct fizzbuzz_t
{
int in; std::string out;
fizzbuzz_t &operator >>( filter_t &f )
{ if( 0==in%f.e ){ out.append( f.t ); } return *this; }
operator const char *()
{ if( out.length() ) return out.c_str(); static char tmp[50]; itoa( in, tmp, 10 ); return tmp; }
};
fizzbuzz_t operator >>( int i, filter_t &f ){ fizzbuzz_t fb; fb.in = i; fb>>f; return fb; }
filter_t fizz = { 3, "Fizz", };
filter_t buzz = { 5, "Buzz", };
filter_t gizz = { 7, "Gizz", };
int main(){ 105>>fizz>buzz>>gizz>>endfb; return 0; }
0260デフォルトの名無しさん
2012/04/13(金) 09:05:55.65合成順が結果に反映される。
結果は標準出力ではなく関数の戻り値として欲しい。
というのが要件だろう。
関数縛りがなければマクロですぐなんだが。
0261デフォルトの名無しさん
2012/04/13(金) 09:09:14.47読まなくても良いくらいC++でのスタンダードな回答。
struct filter_t{ int e; const char *t; };
struct fizzbuzz_t
{
int in; std::string out;
fizzbuzz_t &operator >>( filter_t &f )
{ if( 0==in%f.e ){ out.append( f.t ); } return *this; }
operator const char *()
{ if( out.length() ) return out.c_str();
static char tmp[50]; itoa( in, tmp, 10 ); return tmp; }
};
fizzbuzz_t operator >>( int i, filter_t &f ){ fizzbuzz_t fb; fb.in = i; fb>>f; return fb; }
filter_t fizz = { 3, "Fizz", };
filter_t buzz = { 5, "Buzz", };
filter_t gizz = { 7, "Gizz", };
int main(){ 105>>fizz>buzz>>gizz; return 0; }
0262デフォルトの名無しさん
2012/04/13(金) 09:19:13.99とはいえ、関係ない演算子をしれっとまぎれこませちゃったら失格じゃまいか?
0263デフォルトの名無しさん
2012/04/13(金) 09:30:20.96マクロを使わなくても、型クラスと多値とモナドが賢い言語なら関数でも書けるんじゃね?
0264デフォルトの名無しさん
2012/04/13(金) 09:49:06.63それに hoge を追加することを想定して、
map (hoge . gizz . buzz . fizz) [1, 3, 5, 7, 15, 21, 35, 105] について考える。
関数合成と map の性質より、
map (f . g) [...] = map f (map g [...]) であるから
map (hoge . gizz . buzz . fizz) [1, 3, 5, 7, 15, 21, 35, 105]
= map hoge (map (gizz . buzz . fizz) [1, 3, 5, 7, 15, 21, 35, 105])
= map hoge [1, "FIzz", "Buzz", "Gizz", "FizzBuzz", "FizzGizz", "BuzzGizz", "FizzBuzzGizz"]
よって hoge が書けない。===== 終 ===== 了 =====
-- という風に論破されちゃうのが嫌な自称上流には嫌われるだろうなぁ、
-- Haskell や形式手法はw
0265デフォルトの名無しさん
2012/04/13(金) 10:04:19.47代入しても型は不変だがメソッドを追加したら型が変わる
0266デフォルトの名無しさん
2012/04/13(金) 10:10:13.95Trait named: #FizzBuzz uses: #() category: 'FizzBuzz-Trait'
FizzBuzz >> fizzBuzzPrep
self value isString ifFalse: [thisContext sender receiver: self -> ''].
FizzBuzz >> fizzBuzzReturn
| method nextByte type |
method := thisContext sender sender method.
nextByte := thisContext sender sender method at: thisContext sender sender pc.
type := nextByte // 16.
^(type = 13 and: [FizzBuzz selectors includes: (method literalAt: nextByte \\ 16 + 1)])
ifTrue: [self] ifFalse: [self value ifEmpty: [self key]]
FizzBuzz >> fizz
self fizzBuzzPrep.
(self key isDivisibleBy: 3) ifTrue: [self value: self value, 'Fizz'].
^self fizzBuzzReturn
FizzBuzz >> buzz
self fizzBuzzPrep.
(self key isDivisibleBy: 5) ifTrue: [self value: self value, 'Buzz'].
^self fizzBuzzReturn
FizzBuzz >> gizz
self fizzBuzzPrep.
(self key isDivisibleBy: 7) ifTrue: [self value: self value, 'Gizz'].
^self fizzBuzzReturn
Integer uses: FizzBuzz. Association uses: FizzBuzz.
105 fizz gizz buzz. "=> 'FizzGizzBuzz' "
0267デフォルトの名無しさん
2012/04/13(金) 10:18:03.23putStrLn を削るだけでリストになるんじゃね?
0268デフォルトの名無しさん
2012/04/13(金) 10:45:33.860269デフォルトの名無しさん
2012/04/13(金) 11:19:14.13てか継続をどう使うことを想定してるの?
0270デフォルトの名無しさん
2012/04/13(金) 12:38:39.46"" -> Left n
s -> Right s
fizzT f s n | f n == 0 = s
fizzT _ _ _ | otherwise = ""
fizz = fizzT (`mod` 3) "Fizz"
buzz = fizzT (`mod` 5) "Buzz"
gizz = fizzT (`mod` 7) "Gizz"
main = print $ join [fizz, buzz, gizz] 105
0271デフォルトの名無しさん
2012/04/13(金) 12:50:09.96import Data.Either
join fs n = case concat $ rights $ map (\f -> f n) fs of
"" -> Left n
s -> Right s
fizzT f s n | f n == 0 = Right s
fizzT _ _ _ | otherwise = Right ""
fizz = fizzT (`mod` 3) "Fizz"
buzz = fizzT (`mod` 5) "Buzz"
gizz = fizzT (`mod` 7) "Gizz"
main = print $ join [join [fizz, buzz], gizz] 105
0272デフォルトの名無しさん
2012/04/13(金) 13:14:50.140273デフォルトの名無しさん
2012/04/13(金) 13:43:15.17LLに有利っぽいのに
0274デフォルトの名無しさん
2012/04/13(金) 13:43:49.58また、fizz 105、buzz fizz 105 という式も、同様になんらかの型を持つとする。
すると、
fizz の型は
Int -> a
buzz の型は
(Int -> a) -> Int -> b
gizz の型は
((Int -> a) -> Int -> b) -> (Int -> a) -> Int -> c
というような型でなければならない。無理。というか、どう頑張っても、
先頭に do か何かが要る。
0275デフォルトの名無しさん
2012/04/13(金) 13:56:46.550276デフォルトの名無しさん
2012/04/13(金) 14:00:17.790277デフォルトの名無しさん
2012/04/13(金) 14:04:41.690278デフォルトの名無しさん
2012/04/13(金) 14:24:54.40って言いたいだけで作った問題なのがかなり見え見えなんだが。
0279デフォルトの名無しさん
2012/04/13(金) 15:57:16.91module FizzBuzz
SYM_HASH = {} ; def self.add_fizz sym, n ; SYM_HASH[sym] = n ; end
def self.do_it sym, n, prefix ; if m = SYM_HASH[sym]
if n % m == 0
s = sym.to_s ; s.capitalize!
if prefix.kind_of? String then s[0, 0] = prefix end
s.fizzbuzzval = n ; s
else prefix end else nil end
end
end
class Integer ; def method_missing sym
if it = FizzBuzz.do_it(sym, self, self) then it else super end
end end
class String ; attr_writer :fizzbuzzval ; def method_missing sym
if it = FizzBuzz.do_it(sym, @fizzbuzzval, self) then it else super end
end end
FizzBuzz.add_fizz :fizz, 3
FizzBuzz.add_fizz :buzz, 5
FizzBuzz.add_fizz :gizz, 7
p [1, 3, 5, 7, 15, 21, 35, 105].map{|n|n.fizz.buzz.gizz}
0280デフォルトの名無しさん
2012/04/13(金) 16:17:23.17package FizzBuzzGizz;
sub new {
my ($c, $n) = @_;
bless {n => $n, s => ''}, $c
}
sub fizz {my $t = shift; $t->{s} .= 'Fizz' if 0 == $t->{n} % 3; $t}
sub buzz {my $t = shift; $t->{s} .= 'Buzz' if 0 == $t->{n} % 5; $t}
sub gizz {my $t = shift; $t->{s} .= 'Gizz' if 0 == $t->{n} % 7; $t}
sub result {my $t = shift; $t->{s} ? $t->{s} : $t->{n}}
1;
package main;
do {
my $fbg = new FizzBuzzGizz($_);
print "$_:" . FizzBuzzGizz::result($fbg->fizz->buzz->gizz) . "\n"
# あるいは print "$_:" . $fbg->fizz->buzz->gizz->result . "\n"
} for qw{1 3 5 7 15 21 35 105};
$ perl p_fizzBuzzGizz.pl
1:1
3:Fizz
5:Buzz
7:Gizz
15:FizzBuzz
21:FizzGizz
35:BuzzGizz
105:FizzBuzzGizz
0281デフォルトの名無しさん
2012/04/13(金) 16:22:11.22objectのmethodが返す値はまたobjectだけれど、
printで評価すると判定結果文字列を返すには、
こんな書き方くらいしかないのかな…?
多値のリスト返しでやってみようと思ったけれどうまい方法が思いつかなかったぜよ
0282デフォルトの名無しさん
2012/04/13(金) 17:12:42.66package FizzBuzzGizz;
sub new {
my ($c, $n) = @_;
bless \"$n."
}
sub fizz {my $t=shift; $_=$$t; bless do { /(^\d+)/; 0 == $1 % 3 ? \"${_}Fizz": $t }}
sub buzz {my $t=shift; $_=$$t; bless do { /(^\d+)/; 0 == $1 % 5 ? \"${_}Buzz": $t }}
sub gizz {my $t=shift; $_=$$t; bless do { /(^\d+)/; 0 == $1 % 7 ? \"${_}Gizz": $t }}
1;
package main;
do {
my $fbg = new FizzBuzzGizz($_);
print ${$fbg->fizz->buzz->gizz} . "\n"
} for qw{1 3 5 7 15 21 35 105};
0283デフォルトの名無しさん
2012/04/13(金) 17:29:05.85何縛りのゲームなのかわからんけど、関数合成演算子でも駄目かね?
import Data.Either
import Prelude hiding ((.))
(.) f g n = case concat $ rights [f n, g n] of
[] -> Left n
s -> Right s
fizzT f s n | f n == 0 = Right s
fizzT _ _ _ | otherwise = Right []
fizz = fizzT (`mod` 3) "Fizz"
buzz = fizzT (`mod` 5) "Buzz"
gizz = fizzT (`mod` 7) "Gizz"
main = print $ fizz.buzz.gizz $ 105
0284デフォルトの名無しさん
2012/04/13(金) 17:30:10.61package FizzBuzzGizz;
sub new {
my ($c, $n) = @_;
bless \"$n."
}
sub comm { my ($t, $r, $s) = @_; $$t =~ /(^\d+)/;
0 == $1 % $r ? \"${_}$s": $t }
sub fizz {bless comm((shift), 3, 'Fizz')}
sub buzz {bless comm((shift), 5, 'Buzz')}
sub gizz {bless comm((shift), 7, 'Gizz')}
1;
package main;
for (qw(1 3 5 7 15 21 35 105)) {
print ${new FizzBuzzGizz($_)->fizz->buzz->gizz} . "\n"
}
0285デフォルトの名無しさん
2012/04/13(金) 17:31:15.65class String
attr_accessor :srcint
private
def f(n,s); (@srcint % n == 0) ? (self << s) : (self); end
end
class Integer
private
def f(n,s); (self % n == 0) ? (s.srcint = self; s) : (self); end
end
class Object
def fizz; f(3,'Fizz'); end
def buzz; f(5,'Buzz'); end
def gizz; f(7,'Gizz'); end
end
p [1,3,5,7,15,21,35,105].map{|n| n.fizz.buzz.gizz }
# => [1, "Fizz", "Buzz", "Gizz", "FizzBuzz", "FizzGizz", "BuzzGizz", "FizzBuzzGizz"]
p [1,3,5,7,15,21,35,105].map{|n| n.fizz.gizz.buzz }
# => [1, "Fizz", "Buzz", "Gizz", "FizzBuzz", "FizzGizz", "GizzBuzz", "FizzGizzBuzz"]
0286デフォルトの名無しさん
2012/04/13(金) 17:33:52.32package FizzBuzzGizz;
sub new {
my ($c, $n) = @_;
bless \"$n."
}
sub comm { my ($t, $r, $s) = @_;
0 == $$t % $r ? \"$${t}$s": $t }
sub fizz {bless comm((shift), 3, 'Fizz')}
sub buzz {bless comm((shift), 5, 'Buzz')}
sub gizz {bless comm((shift), 7, 'Gizz')}
1;
package main;
for (qw(1 3 5 7 15 21 35 105)) {
print ${new FizzBuzzGizz($_)->fizz->buzz->gizz} . "\n"
}
0287デフォルトの名無しさん
2012/04/13(金) 17:45:43.30package FizzBuzzGizz;
sub new { my ($c, $n) = @_;
bless \"$n." }
sub com { my ($t, $m, $s) = @_;
bless 0 == $$t % $m ? \($$t.$s): $t }
sub fizz {com(shift, 3, 'Fizz')}
sub buzz {com(shift, 5, 'Buzz')}
sub gizz {com(shift, 7, 'Gizz')}
1;
package main;
for (qw(1 3 5 7 15 21 35 105)) {
print ${new FizzBuzzGizz($_)->fizz->buzz->gizz} . "\n"
}
大差ないか…
0288デフォルトの名無しさん
2012/04/13(金) 17:54:12.600289デフォルトの名無しさん
2012/04/13(金) 17:58:22.56え?なぜ?
0290デフォルトの名無しさん
2012/04/13(金) 18:10:15.39ちゃんと書けているのは今のところRubyだけって感じか。
文字列オブジェクトにインスタンス変数(状態)を持たせられるのが強みだなぁ。
Smalltalkのはやってることが「独立した関数(メソッド)」と呼ぶにはどーよという内容だから失格。
関数型は型システムの制約でこういう仕様の関数モドキは書けないっていうことでFA?
0291デフォルトの名無しさん
2012/04/13(金) 18:22:32.06でも実際のところ、こんな書き方したくないけどね
実際にやるなら、何らかのコンテナにラップしてからmapして
それが終わったら、文字列や数値として取り出すと思う
原文がいきなり数値に対してメソッド呼んでるから、容赦なく組み込みクラスを弄ったが…
0292デフォルトの名無しさん
2012/04/13(金) 18:30:51.940293デフォルトの名無しさん
2012/04/13(金) 18:33:45.54まあクイズだからね。言語機能をどう使って無茶な要件をクリアするかのパズルみたいなもん。
0294デフォルトの名無しさん
2012/04/13(金) 18:35:01.97まずコード出せ。話はそれからだ。
0295デフォルトの名無しさん
2012/04/13(金) 18:57:18.700296デフォルトの名無しさん
2012/04/13(金) 19:00:25.490297デフォルトの名無しさん
2012/04/13(金) 19:35:12.73RubyはメソッドチェインOKなのに
関数型言語はfizz(buzz(gizz))しか認めないんだろ?
そりゃ静的型じゃ無理っつーか制限する意味が分からん
後からgizz等を追加できる拡張性あるコードを
書けないならともかく、そうでもないしな
0298デフォルトの名無しさん
2012/04/13(金) 19:40:42.95-- String "has-a" Integer
data HasA = HasA String Integer
instance Show HasA where show (HasA s n) = if s == "" then show n else show s
fizz (HasA s n) = HasA (s ++ if mod n 3 == 0 then "Fizz" else "") n
buzz (HasA s n) = HasA (s ++ if mod n 5 == 0 then "Buzz" else "") n
gizz (HasA s n) = HasA (s ++ if mod n 7 == 0 then "Gizz" else "") n
main = print $ map (gizz . buzz . fizz . HasA "") [1,3,5,7,15,21,35,105]
0299デフォルトの名無しさん
2012/04/13(金) 19:47:44.31似たようなコード書いてたら先に張られてた
個人的には hasA = HasA "" を定義しておくのが好み
それはともかく、.演算子使ってるからケチ付けられると思うぜ多分w
0300デフォルトの名無しさん
2012/04/13(金) 19:56:22.620301デフォルトの名無しさん
2012/04/13(金) 20:00:44.980302デフォルトの名無しさん
2012/04/13(金) 20:30:30.61var def_fizz = function (name, m) {
var fun = function () {
var tp = typeof this.valueOf();
var n = (tp === 'number') ? this : this.fizzbuzzval
if (n % m === 0) {
var s = name.charAt(0).toUpperCase() + name.slice(1);
if (tp === 'string') {
s = this + s;
}
s = new String(s);
s.fizzbuzzval = n;
return s;
} else {
return this;
}
} ;
Number.prototype[name] = fun;
String.prototype[name] = fun;
} ;
def_fizz('fizz', 3);
def_fizz('buzz', 5);
for (var i = 1; i <= 30; ++i) {
document.writeln(i.fizz().buzz());
}
0303デフォルトの名無しさん
2012/04/13(金) 20:36:17.98http://toro.2ch.net/test/read.cgi/tech/1313183984/190
‥‥ごめんなさい。
0304デフォルトの名無しさん
2012/04/13(金) 22:09:50.27http://toro.2ch.net/test/read.cgi/tech/1313183984/191
0305デフォルトの名無しさん
2012/04/13(金) 22:25:54.85ΟΓΖ
基本データ型のリテラル単独でクラスのインスタンスになり得ない言語である以上、new しないことにははじまらない‥‥。
0307デフォルトの名無しさん
2012/04/13(金) 22:42:51.66newを隠蔽すればいいだけ
0308デフォルトの名無しさん
2012/04/13(金) 23:24:10.63組み込みクラスにメソッドを追加できない言語では
普通に関数で実装すればいいと思うよ。gizz( buzz( fizz( n ) ) )みたいに。
0309デフォルトの名無しさん
2012/04/14(土) 00:02:15.95それが一番シンプルだと思う。
速度も早いだろうしね。
0310デフォルトの名無しさん
2012/04/14(土) 00:25:40.80それがね、gizz() buzz() fizz()の三関数をどれも特別扱いせず、
いずれの戻り値もいずれの引数となり得る柔軟さを備える仕様にし、かつ
print gizz( buzz( fizz( n ) ) )で
1
"Fizz"
"Buzz"
"Gizz"
"FizzBuzz"
"FizzGizz"
"BuzzGizz"
"FizzBuzzGizz"
という出力を得るのは、以外とマンドくさいのよ。
gizz()だけは文字列を返すなどそれぞれの関数のIFを個別に制約すれば子供の使いなみに楽。
つかこういう要求仕様でnewは使うなとか制限もうけること自体が仕様策定の段階でミスなんだろ。
0311デフォルトの名無しさん
2012/04/14(土) 00:32:11.230312デフォルトの名無しさん
2012/04/14(土) 00:51:08.06> .演算子使ってるからケチ付けられると思うぜ多分w
志村! HasA! HasA!
0313デフォルトの名無しさん
2012/04/14(土) 01:11:55.03そしたら、こうだな。
sub com {
my ($mod, $zz, $num, $str) = @_;
$str .= $zz
if 0 == $num % $mod;
$str ? ($num, $str) : $num
}
sub fizz {com(3, 'Fizz', @_)}
sub buzz {com(5, 'Buzz', @_)}
sub gizz {com(7, 'Gizz', @_)}
print "$_: " . gizz(buzz(fizz($_))) . "\n"
for qw(1 3 5 7 15 21 35 105);
実効例:
$ perl p_FizzBuzzGizzAret.pl
1: 1
3: Fizz
5: Buzz
7: Gizz
15: FizzBuzz
21: FizzGizz
35: BuzzGizz
105: FizzBuzzGizz
perlのscalar context/list contextを巧みに?利用してるんで、
それを知らない人には分かりにくいかもしれず、申し訳ないんだか…
※もうちょっと考えて出題して欲しいな、言っちゃ悪いがこういった仕様策定ミスをcodeでカバーすることに何の意味が…
0314デフォルトの名無しさん
2012/04/14(土) 01:16:27.94関数の引数にフラグを一個追加したもの
つまり、
foo(value, false) ・・・ スカラ呼び出し
foo(value, true) ・・・ リスト呼び出し
foo(value, flag)関数の説明
flagがfalseの場合、スカラタイプの値を返します。
flagがturの場合、リストタイプの値を返します。
まあ、こんなもん。
0315デフォルトの名無しさん
2012/04/14(土) 01:24:45.45志村、ここ、ここ。
my ($mod, $zz, $num, $str) = @_;
↑
$str ? ($num, $str) : $num
sub xxx {com(3, 'Fizz', @_)}
↑
print "$_: " . gizz(buzz(fizz($_))) . "\n"
と
print "$_: " , gizz(buzz(fizz($_))) , "\n"
の動作の違い
なんか、中途半端に知っている人が出てきたな…
寝るか…。ノシ
0316デフォルトの名無しさん
2012/04/14(土) 01:45:08.21sub com {
my ($mod, $zz, $num, $str) = @_;
$str .= $zz if 0 == $num % $mod;
$str ? ($num, $str) : $num
}
sub fizz {com(3, 'Fizz', @_)}
sub buzz {com(5, 'Buzz', @_)}
sub gizz {com(7, 'Gizz', @_)}
■ このスレッドは過去ログ倉庫に格納されています