• 一个简单的 todo list
import Data.List
import System.IO
import System.Directory
import System.Environment
import Control.Exception

dispatch :: String -> [String] -> IO ()
dispatch "add" = add
dispatch "view" = view
dispatch "remove" = remove
dispatch _ = showUsage

main = do
    argv <- getArgs
    case argv of
        (command:argList) -> dispatch command argList
        otherwise -> dispatch "" []

add :: [String] -> IO ()
add [fileName, todoItem] = appendFile fileName $ todoItem ++ "\n"

view :: [String] -> IO ()
view [fileName] = do
    contents <- readFile fileName
    let todoTasks = lines contents
        numberedTasks = zipWith (\n line -> show n ++ ": " ++ line) [0..] todoTasks
    putStr $ unlines numberedTasks

remove :: [String] -> IO ()
remove [fileName, numberString] = do
    contents <- readFile fileName
    let todoTasks = lines contents
        number = read numberString
        newItems = unlines $ let (ys,zs) = splitAt number todoTasks in ys ++ (tail zs)
    bracketOnError (openTempFile "." "temp")
        (\(tempName, tempHandle) -> do
            hClose tempHandle
            removeFile tempName)
        (\(tempName, tempHandle) -> do
            hPutStr tempHandle newItems
            hClose tempHandle
            removeFile fileName
            renameFile tempName fileName)

showUsage :: [String] -> IO ()
showUsage _ = do
    putStrLn "usage: ./todo command args"
    putStrLn "command:"
    putStrLn "    add    filename item"
    putStrLn "    view   filename"
    putStrLn "    remove filename index"
$ ghc --make todo
[1 of 1] Compiling Main             ( todo.hs, todo.o )
Linking todo ...
$ ./todo add "todo.txt" "Iron the dishes"
$ ./todo view "todo.txt"
0: Iron the dishes
$ ./todo add "todo.txt" "Dust the dog"
$ ./todo view "todo.txt"
0: Iron the dishes
1: Dust the dog
$ ./todo remove "todo.txt" 0
$ ./todo view "todo.txt"
0: Dust the dog
  • 一个逆波兰式计算器
  • 把列表当作栈
solveRPN :: String -> Double
solveRPN = head . foldl operator [] . words where
    operator (x:y:ys) "*" = (y * x) : ys
    operator (x:y:ys) "+" = (y + x) : ys
    operator (x:y:ys) "-" = (y - x) : ys
    operator (x:y:ys) "/" = (y / x) : ys
    operator (x:y:ys) "^" = (y **x) : ys
    operator (x:xs) "ln" = log x : xs
    operator xs "sum" = [sum xs]
    operator xs num = read num : xs

solveRPN "10 4 3 + 2 * -"              -- 4.0
solveRPN "2 3.5 +"                     -- 5.5
solveRPN "90 34 12 33 55 66 + * - +"   -- -3947.0
solveRPN "90 34 12 33 55 66 + * - + -" -- 4037.0
solveRPN "1 1.71828 + ln"              -- 0.999999327347282
solveRPN "10 10 10 10 sum 4 /"         -- 10.0
solveRPN "2 3 7 + ^"                   -- 1024.0
  • 一个简单的DP
  • Fa[i] = min{ Fa[i-1] + A[i], Fb[i-1] + B[i] + C[i] }
  • Fb[i] = min{ Fb[i-1] + B[i], Fa[i-1] + A[i] + C[i] }
  • Ans = min{ Fa[n], Fb[n] }
import Data.List

data Label = A | B | C deriving (Show)
data Section = Section { getA :: Int, getB :: Int, getC :: Int} deriving (Show)
type Path = [(Label, Int)]
type RoadSystem = [Section]

roadStep :: (Path, Path) -> Section -> (Path, Path)
roadStep (pathA, pathB) (Section a b c) =
    let timeA = sum $ map snd pathA
        timeB = sum $ map snd pathB
        pathToA = if (timeA+a) <= (timeB+b+c) then (A,a):pathA else (C,c):(B,b):pathB
        pathToB = if (timeB+b) <= (timeA+a+c) then (B,b):pathB else (C,c):(A,a):pathA
    in (pathToA, pathToB)

optimalPath :: RoadSystem -> Path
optimalPath roadSystem =
    let (bestA, bestB) = foldl roadStep ([],[]) roadSystem
    in if sum (map snd bestA) <= sum (map snd bestB)
       then reverse bestA
       else reverse bestB

main = do
    contents <- getContents
    let threes = map (map read . words) $ lines contents :: [[Int]]
        roadSystem = map (\[a,b,c] -> Section a b c) threes
        path = optimalPath roadSystem
        pathString = concat $ map (show . fst) path
        pathTime = sum $ map snd path
    putStrLn $ "The best path is: " ++ pathString
    putStrLn $ "Time taken: " ++ show pathTime
$ cat > paths.in
50 10 30
5 90 20
40 2 15
10 8 0
$ ghc --make -O paths.hs
[1 of 1] Compiling Main             ( paths.hs, paths.o )
Linking paths ...
$ ./paths < paths.in
The best path is: BCACBBC
Time taken: 75