轻舟过
在研究Haskell的函数式编程

本帖最后由 轻舟过 于 2012-8-1 00:55 编辑

最近两天做了Haskell 99题中的前20道

函数式编程解决问题的思路还真是不一样

还有函数式编程是不是研究Lisp更好一点。。

题目链接在这里:http://www.haskell.org/haskellwiki/99_questions

相应的还有Prolog、Lisp、Perl、OCaml的99题

论坛的SyntaxHighlighter插件怎么没有Haskell的语法高亮

[mw_shl_code=text,true]-- #1

myLast :: [a] -> a

myLast (x:[]) = x

myLast (x:xs) = myLast xs

-- #2

myButLast :: [a] -> a

myButLast (x1:x2:[]) = x1

myButLast (x1:x2:xs) = myButLast (x2:xs)

-- #3

elementAt :: [a] -> Int -> a

elementAt (x:xs) 1 = x

elementAt (x:xs) idx = elementAt xs (idx - 1)

-- #4

myLength :: [a] -> Int

myLength xs = foldl (+) 0 $ map (\x -> 1) xs

-- #5

myReverse :: [a] -> [a]

myReverse = foldl (\xs x-> x:xs) []

-- #6

isPalindrome :: (Eq a) => [a] -> Bool

isPalindrome xs = xs == myReverse xs

data NestedList a = Elem a | List [NestedList a] deriving (Show)

-- #7

flatten :: NestedList a -> [a]

flatten (Elem x) = [x]

flatten (List lst) = foldl (++) [] $ map flatten lst

-- #8

compress :: (Eq a) => [a] -> [a]

compress [] = []

compress all@(x:xs) = (head $ takeWhile (==x) all):compress(dropWhile (==x) all)

-- #9

pack :: (Eq a) => [a] -> [[a]]

pack [] = []

pack all@(x:xs) = (takeWhile (==x) all):pack(dropWhile (==x) all)

-- #10

encode :: (Eq a) => [a] -> [(Int, a)]

encode [] = []

encode all@(x:xs) = ((myLength $ takeWhile (==x) all), x):encode(dropWhile (==x) all)

data RunLengthCode a = Single a | Multiple Int a deriving (Show)

-- #11

encodeModified :: (Eq a) => [a] -> [RunLengthCode a]

encodeModified [] = []

encodeModified lst = map toRunLengthCode $ encode lst

where toRunLengthCode pair = if fst pair == 1 then (Single (snd pair)) else (Multiple (fst pair) (snd pair))

-- #12

decodeModified :: [RunLengthCode a] -> [a]

decodeModified [] = []

decodeModified ((Single x):xs) = [x] ++ decodeModified(xs)

decodeModified ((Multiple len x):xs) = (replicate len x) ++ decodeModified(xs)

-- #13

encodeDirect :: (Eq a) => [a] -> [RunLengthCode a]

encodeDirect [] = []

encodeDirect all@(x:xs) = code:encodeDirect(dropWhile (==x) all)

where len = myLength $ takeWhile (==x) all

code = if len == 1 then (Single x) else (Multiple len x)

-- #14

dupli :: [a] -> [a]

dupli [] = []

dupli (x:xs) = [x, x] ++ dupli(xs)

-- #15

repli :: [a] -> Int -> [a]

repli [] _ = []

repli (x:xs) cnt = (replicate cnt x) ++ (repli xs cnt)

-- #16

{-

- dropEvery = flip $ \n -> map snd . filter ((n/=) . fst) . zip (cycle [1..n])

-}

dropEvery :: [a] -> Int -> [a]

dropEvery lst cnt = map snd $ filter (\p -> (fst p) `mod` cnt /= 0) $ zip [1..] lst

-- #17

split :: [a] -> Int -> ([a], [a])

split lst len = (take len lst, drop len lst)

-- #18

slice :: [a] -> Int -> Int -> [a]

slice lst start end = fst $ split (drop (start - 1) lst) (end - start + 1)

-- #19

rotate :: [a] -> Int -> [a]

rotate lst num = (drop len lst) ++ (take len lst)

where lstLen = length lst

len = (num `mod` lstLen + lstLen) `mod` lstLen

-- #20

removeAt :: Int -> [a] -> (a, [a])

removeAt num lst = (head lstTail, (take (num - 1) lst) ++ (tail lstTail))

where lstTail = drop (num - 1) lst

[/mw_shl_code]

然后还有spoj上的TEST

[mw_shl_code=text,true]main = do

line <- getLine

if line == "42"

then getContents

else do

putStrLn line

main[/mw_shl_code]

绯色の人形
不清楚额
展开Biu

轻舟过 发表于 2012-11-30 20:08

不清楚额,记得好像lisp的几种方言都看过一下,然后不用都忘记了

好吧#32!

[查看全文]
绯色の人形
不清楚额
展开Biu

轻舟过 发表于 2012-11-30 20:08

不清楚额,记得好像lisp的几种方言都看过一下,然后不用都忘记了

好吧#32!

[查看全文]
轻舟过
原来如此
展开Biu

绯色の人形 发表于 2012-11-30 05:22

原来如此,话说你有用过Racket么?不知怎样

不清楚额,记得好像lisp的几种方言都看过一下,然后不用都忘记了

[查看全文]
绯色の人形
纯函数做好多事会很麻烦
展开Biu

轻舟过 发表于 2012-11-29 14:07

纯函数做好多事会很麻烦

所有的东西都是immutable的,然后要遍历容器什么的就很麻烦 ...

原来如此,话说你有用过Racket么?不知怎样

[查看全文]
轻舟过
不局限于这个
展开Biu

绯色の人形 发表于 2012-11-29 10:36

Haskell纯函数,Lisp不局限于这个,准备先学LISP的说

纯函数做好多事会很麻烦

所有的东西都是immutable的,然后要遍历容器什么的就很麻烦

[查看全文]
绯色の人形
不局限于这个
展开Biu

Haskell纯函数,Lisp不局限于这个,准备先学LISP的说

[查看全文]
绯色の人形
不局限于这个
展开Biu

Haskell纯函数,Lisp不局限于这个,准备先学LISP的说

[查看全文]
轻舟过
技术宅的桜井
展开Biu

技术宅的桜井 发表于 2012-11-21 20:04

看不懂= =

看不懂不奇怪,因为是非常小众的东西

[查看全文]