轻舟过
在研究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

ladace 发表于 2012-8-10 22:27

是么……

我觉得设计Haskell更难一些……(主要是那个无处不在的Monad……颠覆了我世界观……)

lisp代码 ...

其实lisp我也了解不多啦,所以可以无视上面我所说的

haskell其实也才看了一点,还不太了解Monad

lisp的有一种解释就是Lost In Stupid Parentheses,算是对它的调侃

haskell还有哪些语法糖,只知道list的写法是一种语法糖

[查看全文]
ladace
本帖最后由
展开Biu

本帖最后由 ladace 于 2012-8-10 22:28 编辑

轻舟过 发表于 2012-8-10 10:43

其实没lisp牛逼

是么……

我觉得设计Haskell更难一些……(主要是那个无处不在的Monad……颠覆了我世界观……)

lisp代码写长了可读性太差了……反正我是没掌握好代码风格……括号实在是太多……严重影响了代码速度……

相比较lisp的括号,Haskell的语法糖让人很爽……不过我还没尝试过自己写点啥……

作为编译型语言,Haskell已经相当不错了。对我而言,二者各有千秋……侧重不同……

[查看全文]
轻舟过
这个语言太牛逼了
展开Biu

ladace 发表于 2012-8-10 08:55

Haskell~~~~

这个语言太牛逼了……

其实没lisp牛逼

[查看全文]
ladace
这个语言太牛逼了
展开Biu

Haskell~~~~

这个语言太牛逼了……@102#

[查看全文]
Richeir
今晚要写帖子哦
展开Biu

轻舟过 发表于 2012-8-1 13:51

嗯,类似的

`83`

今晚要写帖子哦~

[查看全文]
轻舟过
前原圭一
展开Biu

前原圭一 发表于 2012-8-1 16:36

=_,=不知道lisp和haskell根本上有什么区别

我也不清楚,好像lisp更强大

有人说:

Lisp 与 Haskell 并非同源, Haskell 来自 Miranda , 借鉴了 ML 中的类型推导。 Python的 list comperhension 是来自 haskell, 在 CL中有一个类似的 incf-cl 库可以实现 list comperhension 。 这就是Lisp的强大之处, 它根本就没语法,写出来的就是代码树, Macro就是一个代码生成器。 所以有什么新的语言特性,Lisp都能快速的吸收进来。

实际上, 后来很重要的 循环、OO、异常处理, 在Lisp中都是通过 macro 实现的。

因此,神马都是浮云, 不服Lisp的,可以自己写个 C++, Java 的预处理扩展, 自己实现各种特性, 只是Lisp将这种能力内置了,缩短了进化语言与普通开发之间的距离。人人都能变成语言的改进者。

[查看全文]
前原圭一
我不知道唉
展开Biu

Richeir 发表于 2012-8-1 16:16

Python是啥,能吃么...我不知道唉...

@14*可以吃

Ref: http://en.wikipedia.org/wiki/Pythonidae

[查看全文]
前原圭一
我的程序里用到了
展开Biu

轻舟过 发表于 2012-8-1 16:10

haskell也有let的

我的程序里用到了where,也是差不多的东西

=_,=不知道lisp和haskell根本上有什么区别

[查看全文]