だから、 withdraw :: Int -> Int ではなくて withdraw :: Int -> IO Int になる。別にIO Intにしたからって毎回出力するわけじゃないよ。
24 名前:デフォルトの名無しさん mailto:sage [04/02/15 22:53]
>>22 depositだけ実装。 ============================ module Main where import Data.FiniteMap import Data.Maybe type Database = FiniteMap Int Int -- errors are silently ignored. deposit :: Database -> (Int, Int) -> Database deposit db (nm, mon) = fromMaybe db (lookupFM db nm >>= return . addToFM db nm . (+ mon)) testDB :: Database testDB = listToFM [(0, 100), (1,1000), (2, 300)]
data Cmd = Deposit Int Int | Withdraw Int Int | Print | Error deriving Read
============================ 続く
25 名前:デフォルトの名無しさん mailto:sage [04/02/15 22:54]
============================ main = loop testDB where loop db = do s <- getLine cmd <- catch (readIO s) (\e -> return Error) case cmd of Deposit i m -> do loop $ deposit db (i, m) Print -> do putStrLn $ ">> Status: " ++ show (fmToList db) loop db _ -> do putStrLn ">> Sorry, not implemented" loop db ============================ 終わり
a = [0, 1, 2, 3, 4] てなリストがあったとき、 f 3 a => [[0, 1, 2], [1, 2, 3], [2, 3, 4]] といった値を返す関数 f が欲しいのですが、 Haskell に標準であるでしょうか?
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)
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)
>>71 > f n xs = filter ((==n).length) [take n x | x <- tails xs]
でも素直でわかりやすい。同じだけど:
f n xs = filter ((==n).length) $ map (take n) $ tails xs
「関数のn乗」って関数はなかったんでしたっけ:
f n xs = (iterate chop $ map (take n) $ tails xs) !! n chop (x:xs) = if null xs then [] else x : chop xs
f n xs = map (take n) $ chopn n $ tails xs chopn n xs = fst $ foldr _chopn ([], n) xs where _chopn x (xs, n) = if n > 0 then (xs, n - 1) else (x:xs, 0)
> 「関数のn乗」 (iterate f x) !! n が普通なんだろうけど、 自分でtail recursiveな nest :: (a -> b) -> a -> Int -> b nest' :: (a -> b) -> a -> Int -> b -- strict あたりを書いたほうが、速くていいね。 標準にあったほうがいいというのに同意。
> 手許に処理系ないんだけど、foldl とか (.) とかで簡単に作れそうな。 foldlは無駄な処理をするのでまずい。 composition f n = foldr (.) id $ replicate n f あたりか。
>>77 > 標準にあったほうがいいというのに同意。 ですよね。標準でないのは f^n は複数の n に対して評価する 可能性があるのでリストにキャッシュしておけ,という主張か とも思ったのですが。あっても悪くない気がします。
f n xs = (transpose $ map inits $ tails xs) !! n (制限:n は xs のサイズ以下,無限リスト可)
81 名前:デフォルトの名無しさん mailto:sage [04/02/29 06:43]
なんとなくテクニックの紹介をしてみる。
Haskellのリストは一つの型しか保持できない。 しかし、複数の型であっても、その間に「関係」があれば、 それらの型をラップし、一つのリストにいれた上で使用することができる。 -------------- {-# OPTIONS -fglasgow-exts #-} -- different types data A = A String deriving Show methA (A x) = length x data B = B Int deriving Show methB (B x) = x -- but they have the methods of the same return type Int data C = forall x. C x (x -> Int) runC (C x f) = f x testC = map runC [C (A "I am A") methA, C (B 100) methB] -- if they belong to the same type class data ShowC = forall x. (Show x) => ShowC x instance Show ShowC where show (ShowC x) = show x testShowC = show [ShowC $ A "I am A", ShowC $ B 100] -- nearly nonsense data X = forall x. X x
--- Hello.hs module Main where import Graphics.UI.WX
main :: IO () main = start hello
hello :: IO () hello = do f <- frame [text := "Hello world!"] quit <- button f [text := "Quit", on command := close f] set f [layout := widget quit] ---
>>113 > 題意のような関数を返すのですが、部分適用という感じがしません。 addNum'' n m = n + m に部分適用を使ったといっているのだからそれでいいだろう。 sigmaPartial f n = sum [f m | m <- [0..n]]
> (あと、なんか lambda版を、内包表現とか使ってて、出題意図に沿ってないような気がするのです) それなら使わなければいいのでは? sigmaLambda = \f n -> if n == 0 then f 0 else sigmaLambda f (n - 1) + f n
115 名前:デフォルトの名無しさん [04/04/14 14:00]
sigma,sigma' :: (Int -> Int) -> (Int -> Int) sigma f = \ n -> foldl (\ s i -> s + f i) 0 [0..n] sigma' f = let iter s x = if x < 0 then s else iter (s+f x) (x-1) in iter 0