[過去ログ]
関数型プログラミング言語Haskell Part16 (978レス)
関数型プログラミング言語Haskell Part16 http://echo.5ch.net/test/read.cgi/tech/1317958045/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
766: デフォルトの名無しさん [sage] 2011/12/20(火) 16:29:36.21 742がやってることはホームレスを無差別にいじめてる事と同じでしょ。 http://echo.5ch.net/test/read.cgi/tech/1317958045/766
767: デフォルトの名無しさん [] 2011/12/20(火) 21:54:07.97 listAは重複がないリストとする。 listBは空でなく、順序は不明だがlistAの要素の連続になっている。 listAの要素であるxを渡された時、それがlistBと比較して前方にあるか 後方にあるか、それともlistBに含まれるかを判定したい。 例で書くと listA = ["A","B","C","D","E",...] listB = ["C","D","B"] xが"E"なら、listBに含まれるB,C,Dに対して「後方」ということになる。 このとき、haskellらしい考え方だとどういうアプローチになる? 俺の手続き脳だと 1. xがlistBにあるかどうかを判別 2. xとlistBそれぞれの要素のlistA内での位置を調べる 3. 調べた位置を比較して「前方」「後方」を判定する と考えたんだけど、ザ・手続きっぽくてダサいよなぁ、と思って。 http://echo.5ch.net/test/read.cgi/tech/1317958045/767
768: デフォルトの名無しさん [sage] 2011/12/20(火) 22:49:41.06 こんな感じ? filter (flip all listB . (/=)) listA http://echo.5ch.net/test/read.cgi/tech/1317958045/768
769: デフォルトの名無しさん [sage] 2011/12/20(火) 22:52:12.32 ごめん問題読んでなかった。取り除くんじゃないのな。 http://echo.5ch.net/test/read.cgi/tech/1317958045/769
770: デフォルトの名無しさん [sage] 2011/12/20(火) 22:55:42.52 >>767 めっさ力技 data Pos = F | M | E deriving Show getPos :: Eq a => [a] -> [a] -> a -> (Maybe Pos) getPos listA listB = fmap f . (`lookup`listE) where listC = map (`elem` listB) listA listE = zip listA $ zip listC $ scanl1 (||) listC f (True,_) = M f (False,False) = F f (False,True) = E listA = [0,1,2,3,4] listB = [2,3,1] x=0 main = do let g = getPos listA listB print $ g 0 print $ g 1 print $ g 2 print $ g 3 print $ g 4 http://echo.5ch.net/test/read.cgi/tech/1317958045/770
771: デフォルトの名無しさん [sage] 2011/12/20(火) 23:35:56.81 >>767 1. listAをlistA1 ++ [x] ++ listA2にわける 2. listA1とlistBのintersectionを取って判定 f listA listB x = if y == 0 then 1 else if y == length listB then -1 else 0 where y = length $ takeWhile (/= x) listA `intersect` listB http://echo.5ch.net/test/read.cgi/tech/1317958045/771
772: デフォルトの名無しさん [sage] 2011/12/21(水) 01:20:13.13 >>767 f listA listB x = (elem x as, elem x listB) where as = takeWhile (not.flip elem listB) listA http://echo.5ch.net/test/read.cgi/tech/1317958045/772
773: デフォルトの名無しさん [sage] 2011/12/21(水) 08:25:55.14 >>771 (y == 0)のあとに(elem x listB)でもう一回場合分けが必要でない? http://echo.5ch.net/test/read.cgi/tech/1317958045/773
774: デフォルトの名無しさん [sage] 2011/12/21(水) 12:32:22.50 >>759 元々4月の予定だったよな…… http://echo.5ch.net/test/read.cgi/tech/1317958045/774
775: デフォルトの名無しさん [sage] 2011/12/21(水) 12:43:01.28 >>767 の解法としていくつか提示された例は、 たとえば1ヶ月後とかに自分が読んでも、あるいは他人が読んでも、 どんな計算をして答えを求めているのか簡単に分かるもんなの? http://echo.5ch.net/test/read.cgi/tech/1317958045/775
776: デフォルトの名無しさん [sage] 2011/12/21(水) 16:52:03.13 listBの要素はソートすればlistAの連続部分列になるってこと? http://echo.5ch.net/test/read.cgi/tech/1317958045/776
777: デフォルトの名無しさん [sage] 2011/12/21(水) 17:20:50.31 >>776 listAは整列だという仮定はない。「listAでの出現位置」に基づいてソートするなら話は別だが。 http://echo.5ch.net/test/read.cgi/tech/1317958045/777
778: デフォルトの名無しさん [sage] 2011/12/21(水) 19:40:34.62 >>767 data Where = Before | Here | After whereIncluded :: (Eq a) => [a] -> [a] -> a -> Where whereIncluded _ [] _ = After whereIncluded (a:as) (b:bs) x | x == b = Here | x == a = if elem x bs then Here else Before | otherwise = whereIncluded as bs x [説明] ・listA と listB それぞれの head と x を比較する ・listB の head と x が同じなら、x は listB に含まれる ・そうではなく listA の head と x が同じ場合、 x が listB に含まれていなければ、x は後方にある ・どちらの head とも異なっていれば、両者の tail に対して同計算を繰り返す ・計算を繰り返した結果 listB の tail が空なら、x は後方にある 提示された条件を全て完全に満たすものとして式を書いたので、 エラー処理は省いてある http://echo.5ch.net/test/read.cgi/tech/1317958045/778
779: 767 [sage] 2011/12/21(水) 21:02:56.56 >>770,771,772,778 まさかこんなに素早く返事があるとは思ってなくて 反応遅れました。すみません。 具体的なコード例までわざわざありがとうございます。 見事に誰一人としてelemIndexなんて使ってないですね……。 順序を調べる、という発想自体を捨てないと駄目だということが よくわかりました。 >>775 個人的には770さんの例以外は見て何をしているかは すぐ把握できました。 >>776 777さんが返してくれていますが、listAは整列とは限らないです。 listAの位置に基づいてlistBをソートすれば、listBは確かに連続 部分列になります。 というわけで、どうも皆さんありがとうございました。 http://echo.5ch.net/test/read.cgi/tech/1317958045/779
780: デフォルトの名無しさん [sage] 2011/12/22(木) 05:28:49.45 >>778 whereIncluded [1..6] [5] 4 = whereIncluded [2..6] [] 4 = After http://echo.5ch.net/test/read.cgi/tech/1317958045/780
781: デフォルトの名無しさん [sage] 2011/12/22(木) 07:22:14.40 >>780 あぁなるほど、そうか ちょっと修正案を考えてみる http://echo.5ch.net/test/read.cgi/tech/1317958045/781
782: 778 [sage] 2011/12/22(木) 07:52:15.94 >>780 に指摘されて修正案を考えてる時に、 全然違うアイデアが思い浮かんだんだが、 これは今まで出てきたかな(特に >>771 と同類か) listA から x の位置を探す x の位置の直後から http://echo.5ch.net/test/read.cgi/tech/1317958045/782
783: 778 [sage] 2011/12/22(木) 07:55:25.77 途中でレスってしまった >>780 に指摘されて修正案を考えてる時に、 全然違うアイデアが思い浮かんだんだが、 これは今まで出てきたかな(特に >>771 と同類か) listA から x の位置を探す x の位置の直後から listB の要素数分の要素をリストとして取り出す listC x が listB に無い場合、head listB が listC に有れば「前」 head listB が listC に無ければ「後ろ」 http://echo.5ch.net/test/read.cgi/tech/1317958045/783
784: 778 [sage] 2011/12/22(木) 08:55:12.79 >>783 訂正 > x の位置の直後から listB の要素数分の要素をリストとして取り出す listC x の位置の直後から末端までをリストとして取り出す listC http://echo.5ch.net/test/read.cgi/tech/1317958045/784
785: 778 [sage] 2011/12/22(木) 12:54:37.61 >>783,784 式にするとこんな感じ whereIncluded :: (Eq a) => [a] -> [a] -> a -> Where whereIncluded as bs@(b:_) x | elem x bs = Here | elem b as' = After | otherwise = Before where as' = takeWhile (/=x) as ダサいかな http://echo.5ch.net/test/read.cgi/tech/1317958045/785
786: デフォルトの名無しさん [sage] 2011/12/22(木) 20:08:59.62 Haskell Platform じゃなくて素の GHC の方には、 random パッケージってデフォルトでは入ってないんだね 地味に驚いた http://echo.5ch.net/test/read.cgi/tech/1317958045/786
787: デフォルトの名無しさん [sage] 2011/12/22(木) 21:36:01.61 QuickCheck を調べてて、ステキなリファクタリング テクニックに出会った http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck リファクタリング前は(インデントに全角スペースを入れた)、 getList = find 5 where find 0 = return [] find n = do ch <- getChar if ch `elem` ['a'..'e'] then do tl <- find (n-1) return (ch : tl) else find n というコードなんだが、副作用がある処理と無い式とが混ざっててテストし難い (また、全体の処理もぱっと見分かりにくい) これがリファクタリングで次のようになる getList :: IO [Char] getList = fmap take5 getContents take5 :: [Char] -> [Char] take5 = take 5 . filter (`elem` ['a'..'e']) ちょっと感動した こういうことがサラっとできるようになりたいもんだ http://echo.5ch.net/test/read.cgi/tech/1317958045/787
788: デフォルトの名無しさん [sage] 2011/12/22(木) 21:56:17.35 遅延I/O怖い>< http://echo.5ch.net/test/read.cgi/tech/1317958045/788
789: デフォルトの名無しさん [] 2011/12/22(木) 22:55:08.11 モナドって大した概念なの? http://echo.5ch.net/test/read.cgi/tech/1317958045/789
790: デフォルトの名無しさん [sage] 2011/12/22(木) 22:59:36.72 ものごとを抽象化するための仕組みとしては大したもんだよ http://echo.5ch.net/test/read.cgi/tech/1317958045/790
791: デフォルトの名無しさん [] 2011/12/23(金) 10:28:44.71 >>790 なんかいい例希望 モナドはものごと全部を抽象化するんじゃないよね? http://echo.5ch.net/test/read.cgi/tech/1317958045/791
792: デフォルトの名無しさん [sage] 2011/12/23(金) 10:30:00.16 STMとか? http://echo.5ch.net/test/read.cgi/tech/1317958045/792
793: デフォルトの名無しさん [] 2011/12/23(金) 12:02:29.11 >>790 >>791 そうだな。なんでも抽象化できるんならこれまた意味不明になるし。 だいたい、何なんだよ抽象化って。 http://echo.5ch.net/test/read.cgi/tech/1317958045/793
794: デフォルトの名無しさん [sage] 2011/12/23(金) 17:44:45.43 モナドによる抽象化ってのは、だいたい(Monad m) =>で始まる型のある関数を書くこと 具体例はControl.Monadとか見れば http://echo.5ch.net/test/read.cgi/tech/1317958045/794
795: デフォルトの名無しさん [sage] 2011/12/23(金) 17:52:14.34 それで、何をどう抽象できて、何は抽象できないの? モナドで抽象する前と後とで何が変わるの? http://echo.5ch.net/test/read.cgi/tech/1317958045/795
メモ帳
(0/65535文字)
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
あと 183 レスあります
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.011s