[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 05/09 11:45 / Filesize : 259 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

関数型プログラミング言語Haskell Part3



1 名前:デフォルトの名無しさん [04/02/10 22:16]
Haskellの公式HP
www.haskell.org/
日本語サイト
www.sampou.org/cgi-bin/haskell.cgi
www.teu.ac.jp/kougi/koshida/Prog6/index.html

過去ログ、関連スレは>>2-5

36 名前:デフォルトの名無しさん mailto:sage [04/02/19 14:33]
List.hsとPrelude.hsを探したけど、無かった。
無いとは言いきれないけどね。
いちおうお求めの関数は
f :: Int -> [a] -> [[a]]
f num lst
| length lst >= num = take num lst : f num (tail lst)
| otherwise = []
でいいとは思います。

37 名前:デフォルトの名無しさん mailto:sage [04/02/19 14:41]
あ、インデントが。
f num lst以下の2文はインデントを深くしないと、だめです。
いちおう念のため。

38 名前:デフォルトの名無しさん mailto:sage [04/02/19 14:57]
myTakeを定義しておいて、(長さが足りないとNothing)

g :: Int -> [a] -> [[a]]
g num lst = mapMaybe (myTake num) (tails lst)

これだとlst >> numでもOK

39 名前:デフォルトの名無しさん mailto:sage [04/02/19 15:01]
myTake :: Int -> [a] -> Maybe [a]
myTake n _ | n < 0 = Nothing
myTake n _ | n == 0 = Just []
myTake n (x:xs) = case myTake (n-1) xs of
Just xxs -> Just (x:xxs)
Nothing -> Nothing
myTake _ [] = Nothing

40 名前:デフォルトの名無しさん mailto:sage [04/02/19 15:37]
takeMaybe :: Int -> [a] -> Maybe [a]
takeMaybe n []
| n == 0 = Just []
| otherwise = Nothing
takeMaybe n (x:xs)
| n < 0 = Nothing
| n == 0 = Just []
| otherwise = takeMaybe (n-1) xs >>= \r
-> Just (x:r)



41 名前:デフォルトの名無しさん mailto:sage [04/02/19 16:59]
>>30 wc.hs 書いてる人につっこみ。
data は複数形、単数は datum.

-- 知っててやってるんだったら無視して下さい。
-- (data って変数名使えないから、とか。)

あと下から4行目の data は datas の typo でしょう。


42 名前:デフォルトの名無しさん mailto:sage [04/02/19 17:00]
こんなのでもいいかも。

import List
h num lst = [ take num x | x <- tails lst, length x >= num ]

i num = map (take num) . filter ((>=num) . length) . tails

43 名前:デフォルトの名無しさん mailto:sage [04/02/19 17:03]
だんだんエレガントにしようとするところが関数型言語スレらしいな。
#############################
import Data.Maybe
-- 再帰で書いてみた
f n xs = catMaybes $ f' n xs
    where   
        f' n [] = []
        f' n xxs@(x:xs) = (takeJust n xxs):f' n xs

-- AKA myTake and takeMaybe
takeJust 0 xs = Just []
takeJust n [] = Nothing
takeJust n (x:xs) = takeJust (n - 1) xs >>= \xs -> Just (x:xs)

44 名前:デフォルトの名無しさん mailto:sage [04/02/19 17:12]
>>42
>>36(無限リストにつかえない、何度もlengthを求める)よりは
いいけど、takeとlengthを両方使うのは無駄がおおいのでいまいちかと。

-- テストしてない。多分遅い。
h num lst = filter ((== n) . length) $ f' num lst 
  where 
    f' num [] = []
    f' num lst = take num lst:f' num (tail lst)



45 名前:デフォルトの名無しさん mailto:sage [04/02/19 17:15]
>>44
訂正
  >>36(無限リストにつかえない、何度もlengthを求める)よりは
と同じだね。

46 名前:デフォルトの名無しさん mailto:sage [04/02/19 17:22]
>>41
そうか、そういえばそうだったな。
datasなんて単語はないのか。
指摘してくれてありがとう。
ま、いまのところは和製英語ってことで...。
そのうち直します。
日本人だと変数名には苦労するよね。

タイプミスは直しておきました。

47 名前:デフォルトの名無しさん mailto:sage [04/02/19 17:42]
>>44
なるほど。
lengthを軽々しく使わないほうがいいのかもな。
じゃあ、こんなので

j num = map (take num) . filter (biggerOrEqual num) . tails

biggerOrEqual :: Int -> [a] -> Bool
biggerOrEqual 0 _ = True
biggerOrEqual n [] = False
biggerOrEqual n (x:xs) = biggerOrEqual (n-1) xs

48 名前:デフォルトの名無しさん mailto:sage [04/02/19 18:05]
>>47
無限リスト対応問題のほうはそれでいけるね。

>  biggerOrEqual :: Int -> [a] -> Bool
こういうのが欲しくなることは結構ある。おれは
大体再帰で頭を落としていくようにくむから、[]との比較ですむけど。
書くならこうかな。

biggerOrEqual n xs = [] /= drop n xs

49 名前:48 mailto:sage [04/02/19 18:08]
biggerOrEqual  -> longerThan

50 名前:デフォルトの名無しさん mailto:sage [04/02/19 18:14]
longerThan だと Equal が含まれないよ。


51 名前:48 mailto:sage [04/02/19 18:21]
>>50
だからそうかえたんだよ。

52 名前:デフォルトの名無しさん mailto:sage [04/02/19 18:26]
>>48
なるほど、dropはnが大きすぎると[]を返すんだね。
きれいなやりかただ。

で、35の関数はわかりやすさと効率を考えると
以下のものがいいということになる?

38とほぼ同じ。少し見やすくしてみた。
効率がいいのはこれなのかな。
それとnum < 0のときはデフォルトのエラーを起こすようにした。

k num = mapMaybe (takeOfMine num) . tails

takeOfMine 0 _ = Just []
takeOfMine n [] = Nothing
takeOfMine n (x:xs) = maybe Nothing (Just . (x:)) $ takeOfMine (n-1) xs

53 名前:デフォルトの名無しさん mailto:sage [04/02/19 18:39]
>>52
そんなもんかな。
# 個人的にはtakeOfMineは>>43のtakeJustのほうが
# Haskellらしくて好きだけどね。(48 == 43だったりする:-)

54 名前:デフォルトの名無しさん mailto:sage [04/02/19 19:02]
>>53
Maybe Monadってやつね。
僕も好きだな。
でもこっちのほうが好き。

takeJust n (x:xs) = do xs <- takeJust (n-1) xs
return (x:xs)

なんか手続き型言語に擬態してるかんじが好き。



55 名前:デフォルトの名無しさん mailto:sage [04/02/19 19:08]
なんだろ、インデントが重要な言語だと、困るよね。
どうしたらいいんだろう。
上の例ではreturn (x:xs)はxs <- takeJust ...にきっちり合わせないとエラー。

56 名前:by Chalice mailto:sage [04/02/19 19:30]
>>55
> なんだろ、インデントが重要な言語だと、困るよね。
いや、困らん。
…でも困る人は{...;..;.}って書けばいい。

とここまでかいて、他の人はIEとかで
プロポーショナルフォントでみているのだと気づいた。困るかも。

57 名前:デフォルトの名無しさん [04/02/19 21:47]
k 0 がポイント:

k 0 xs = [[]] ++ [[]|x <- xs]
k n xs = [x:y|(x,y) <- zip xs (k (n-1) (tail xs))]

58 名前:デフォルトの名無しさん mailto:sage [04/02/19 22:00]
>>56
  インデントを掲示板でちゃんと表示できたらいいと思ったからさ。

> takeJust n (x:xs) = do xs <- takeJust (n-1) xs
> return (x:xs)

こう書けばいいのかな。

59 名前:デフォルトの名無しさん mailto:sage [04/02/19 23:27]
>> 57
同じトピック内で同名関数が定義されたため、参照透明性が破られてしまいますた。

は冗談として、
m 1 xs = [[x] | x <- xs]
m n xs = [x:xs | (x,xs) <- zip xs $ m (n-1) $ tail xs]
でどうだろう。

60 名前:デフォルトの名無しさん mailto:sage [04/02/20 06:33]
>>57,59
かなりきれいな解法だと思う。
いままでで一番いいかも。

61 名前:デフォルトの名無しさん [04/02/20 13:47]
>>59
いや,f 0 にはそれなりの根拠があるので生かしておいて

f n [] = []
f n xxs@(x:xs) = top n xxs ++ f n xs
top 0 xs = [[]]
top n [] = []
top n (x:xs) = map (x:) $ top (n-1) xs

62 名前:デフォルトの名無しさん [04/02/20 13:52]
xxs@(x:xs)は不要なパターンでした

f n [] = []
f n xs = top n xs ++ f n (tail xs)
top 0 xs = [[]]
top n [] = []
top n (x:xs) = map (x:) $ top (n-1) xs


63 名前:デフォルトの名無しさん mailto:sage [04/02/20 16:24]
>>61
take* n ≒ top だね。map, ++ の使いかたあたりが微妙に遅そうにみえる。
>>57が綺麗でよさそう。
#  k 0 xs = []:[[]|x <- xs]
#  k n xs = zipWith (:) xs (k (n-1) (tail xs))

64 名前:デフォルトの名無しさん [04/02/20 16:29]
zipWith ... 忘れていたよ。









[ 続きを読む ] / [ 携帯版 ]

次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<259KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef