Created
February 26, 2015 06:00
-
-
Save MiyamonY/987e78242f1a84246faa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.List | |
import Data.Char | |
import qualified Data.Map as Map | |
-- head' :: [a] -> a | |
-- head' [] = error "Can't call head on an emply list, dummy!" | |
-- head' (x : _) = x | |
tell :: (Show a) => [a] -> String | |
tell [] = "The list is empty" | |
tell (x:[]) = "The list is has one elements :" ++ show x | |
tell (x : y : []) = "The list has two elements : " ++ show x ++ " and "++ show y | |
tell (x : y : _) = "The list is long. The first two elements are : " ++ show x ++ " show " ++ show y | |
badAdd :: (Num a) => [a] -> a | |
badAdd (x:y:z:[])= x + y + z | |
-- as pattern | |
firstLetter :: String -> String | |
firstLetter "" = "Empty string, whoops!" | |
firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] | |
-- pattern match | |
-- bmiTell :: Double -> String | |
-- bmiTell bmi | |
-- | bmi <= 18.5 = "You're underwieght , you emo, you!" | |
-- | bmi <= 25.0 = "You're suppodedly normal." | |
-- | bmi <= 30.0 = "You're fat!" | |
-- | otherwise = "You'are a whale" | |
-- bmiTell :: Double -> Double -> String | |
-- bmiTell weight height | |
-- | weight / height ^ 2 <= 18.5 = "You're underwieght , you emo, you!" | |
-- | weight / height ^ 2 <= 25.0 = "You're suppodedly normal." | |
-- | weight / height ^ 2 <= 30.0 = "You're fat!" | |
-- | otherwise = "You'are a whale" | |
max' :: (Ord a) => a -> a -> a | |
max' a b | |
| a <= b = b | |
| otherwise = a | |
myCompare :: (Ord a) => a -> a -> Ordering | |
a `myCompare` b | |
| a == b = EQ | |
| a <= b = LT | |
| otherwise = GT | |
-- where | |
bmiTell :: Double -> Double -> String | |
bmiTell weight height | |
| bmi <= skinny = "You're underwieght , you emo, you!" | |
| bmi <= normal = "You're suppodedly normal." | |
| bmi <= fat = "You're fat!" | |
| otherwise = "You'are a whale" | |
where bmi = weight / height ^ 2 | |
skinny = 18.5 | |
normal = 25.0 | |
fat = 30.0 | |
-- scope of where | |
-- greet :: String -> String | |
-- greet "Juan" = niceGreeting ++ "Juan" | |
-- greet "Fernando" = niceGreeting ++ "Fernando!" | |
-- greet name = badGreeting ++ name | |
-- where niceGreeting = "Hello! So very nice to meet you" | |
-- badGreeting = "Oh! Pfft. It's you." | |
niceGreeting :: String | |
niceGreeting = "Hello! So very nice to meet you" | |
badGreeting :: String | |
badGreeting = "Oh! Pfft. It's you." | |
greet :: String -> String | |
greet "Juan" = niceGreeting ++ "Juan" | |
greet "Fernando" = niceGreeting ++ "Fernando!" | |
greet name = badGreeting ++ name | |
-- pattern match and where | |
initials :: String -> String -> String | |
initials firstname lastname = [f] ++ " . " ++ [l] ++ "." | |
where (f:_) = firstname | |
(l:_) = lastname | |
-- functions in where block | |
-- calcBmi :: [(Double, Double)] -> [Double] | |
-- calcBmi xs = [bmi w h | (w, h) <- xs] | |
-- where bmi weight height = weight / height ^ 2.0 | |
-- let expression | |
cylinder :: Double -> Double -> Double | |
cylinder r h = | |
let sideArea = 2 * pi * r * h | |
topArea = pi * r ^ 2 | |
in sideArea + 2 * topArea | |
-- let in list expressions | |
calcBmis :: [(Double, Double)] -> [Double] | |
calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0] | |
-- case expressions | |
head' :: [a] -> a | |
head' [] = error "No head for empty lists!" | |
head' xs = case xs of [] -> error "No head for empty lists!" | |
(x: _) -> x | |
describeList :: [a] -> String | |
describeList ls = "The list is " ++ | |
case ls of [] -> "empty." | |
[x] -> "a singleton list." | |
xs -> "a longer list." | |
-- recursion | |
maximum' :: (Ord a) => [a] -> a | |
maximum' [] = error "maximum of empty list." | |
maximum' [x] = x | |
maximum' (x:xs) = max x (maximum xs) | |
replicate' :: Int -> a -> [a] | |
replicate' n x | |
| n <= 0 = [] | |
| otherwise = x : replicate (pred n) x | |
take' :: Int -> [a] -> [a] | |
take' n _ | |
| n <= 0 = [] | |
take' _ [] = [] | |
take' n (x:xs) = x : take' (pred n) xs | |
repeat' :: a -> [a] | |
repeat' x = x : repeat' x | |
zip' :: [a] -> [b] -> [(a, b)] | |
zip' _ [] = [] | |
zip' [] _ = [] | |
zip' (x:xs) (y:ys) = (x, y) : zip' xs ys | |
-- elem | |
elem' :: (Eq a) => a -> [a] -> Bool | |
a `elem'` [] = False | |
a `elem'` (x:xs) | |
| a == x = True | |
| otherwise = a `elem'` xs | |
-- quicksort | |
quicksort :: (Ord a) => [a] -> [a] | |
quicksort [] = [] | |
quicksort (x:xs) = | |
let smallerOrEqual = [a | a <- xs, a <= x] | |
larger = [a | a <- xs, a > x] | |
in | |
(quicksort smallerOrEqual) ++ [x] ++ (quicksort larger) | |
-- Curry | |
compareWithHundred :: Int -> Ordering | |
compareWithHundred x = compare 100 x | |
-- Section | |
divideByTen :: (Floating a) => a -> a | |
divideByTen = (/10) | |
isUpperAlphanum :: Char -> Bool | |
isUpperAlphanum = (`elem` ['A'..'Z']) | |
-- Higher order function | |
applyTwice :: (a -> a) -> a -> a | |
applyTwice f a = f (f a) | |
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c] | |
zipWith' _ [] _ = [] | |
zipWith' _ _ [] = [] | |
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys | |
flip' :: (a -> b -> c) -> (b -> a -> c) | |
flip' f = g | |
where g x y = f y x | |
-- map | |
map' :: (a -> b) -> [a] -> [b] | |
map' _ [] = [] | |
map' f (x:xs) = (f x) : map' f xs | |
-- filter | |
filter' :: (a -> Bool) -> [a] -> [a] | |
filter' _ [] = [] | |
filter' f (x:xs) | |
| f x = x : filter' f xs | |
| otherwise = filter' f xs | |
quicksort2 :: (Ord a) => [a] -> [a] | |
quicksort2 [] = [] | |
quicksort2 (x:xs) = | |
let smallerOrEq = filter (<= x) xs | |
larger = filter (> x) xs | |
in quicksort2 smallerOrEq ++ [x] ++ quicksort2 larger | |
-- more map and filter | |
largestDivisible :: Integer | |
largestDivisible = head (filter p [100000, 99999..]) | |
where p x = x `mod` 3829 == 0 | |
chain :: Integer -> [Integer] | |
chain 1 = [1] | |
chain n | |
| even n = n : chain (n `div` 2) | |
| odd n = n : chain (n * 3 + 1) | |
numLongChains :: Int | |
numLongChains = length (filter isLong (map chain [1..100])) | |
where isLong xs = length xs > 15 | |
-- lambda function | |
numLongChains' :: Int | |
numLongChains' = length (filter (\ xs -> length xs > 15) (map chain [1..100])) | |
addThree' :: Int -> Int -> Int -> Int | |
addThree' = \x -> \y -> \z -> z + y + z | |
-- foldl | |
sum' :: (Num a) => [a] -> a | |
-- sum' xs = foldl (\acc x -> acc + x) 0 xs | |
sum' = foldl (\acc x -> acc + x) 0 | |
-- foldr | |
map'' :: (a -> b) -> [a] -> [b] | |
map'' f xs = foldr (\ x acc -> f x : acc ) [] xs | |
elem'' :: (Eq a) => a -> [a] -> Bool | |
elem'' y ys = foldr (\x acc -> if x == y then True else acc) False ys | |
-- foldl1 and foldr1 | |
maximum'' :: (Ord a) => [a] -> a | |
maximum'' = foldl1 max | |
-- examples of fold | |
reverse' :: [a] -> [a] | |
reverse' = foldl (flip (:)) [] | |
product' :: (Num a) => [a] -> a | |
product' = foldl (*) 1 | |
filter'' :: (a -> Bool) -> [a] -> [a] | |
filter'' p = foldr (\ x acc -> if p x then x : acc else acc) [] | |
last' :: [a] -> a | |
last' = foldl1 (\ _ x -> x) | |
-- fold infinite list | |
and' :: [Bool] -> Bool | |
and' xs = foldr (&&) True xs | |
-- scan | |
sqrtSums :: Int | |
sqrtSums = length (takeWhile (<1000) (scanl1 (+) (map sqrt [1..]))) + 1 | |
oddSquareSum :: Integer | |
oddSquareSum = sum . takeWhile (<1000) . filter odd $ map (^2) [1..] | |
-- module | |
numUniques :: (Eq a) => [a] -> Int | |
numUniques = length . nub | |
wordNums :: String -> [(String, Int)] | |
wordNums = map (\ ws -> (head ws, length ws)) . group . sort . words | |
-- isInfixOf | |
isIn :: (Eq a) => [a] -> [a] -> Bool | |
needle `isIn` haystack = any (needle `isPrefixOf`) (tails haystack) | |
encode :: Int -> String -> String | |
encode offset msg = map (\ c -> chr $ ord c + offset) msg | |
decode :: Int -> String -> String | |
decode offset = map (\ c -> chr $ ord c - offset) | |
digitSum :: Int -> Int | |
digitSum = sum . map digitToInt . show | |
firstTo40 :: Maybe Int | |
firstTo40 = find (\ x -> digitSum x == 40) [1..] | |
firstTo :: Int -> Maybe Int | |
firstTo n = find (\ x -> digitSum x == n) [1..] | |
-- Assoc | |
-- phoneBook = [("betty", "555-2938"), | |
-- ("bonnie", "452-2928"), | |
-- ("patsy", "493-2928")] | |
findKey :: (Eq k) => k -> [(k,v)] -> Maybe v | |
-- findKey _ [] = Nothing | |
-- findKey key ((k,v):xs) | |
-- | key == k = Just v | |
-- | otherwise = findKey key xs | |
findKey key xs = foldr f Nothing xs | |
where f (k, v) acc = if key == k then Just v else acc | |
-- Data.Map | |
phoneBook :: Map.Map String String | |
phoneBook = Map.fromList $ | |
[("betty", "555-2938"), | |
("betty", "342-2492"), | |
("bonnie", "452-2928"), | |
("patsy", "493-2928")] | |
phoneBook2 :: [(String, String)] | |
phoneBook2 = [("betty", "555-2938"), | |
("betty", "342-2492"), | |
("bonnie", "452-2928"), | |
("patsy", "493-2928")] | |
string2digits :: String -> [Int] | |
string2digits = map digitToInt . filter isDigit | |
phoneBookToMap :: (Ord k) => [(k, String)] -> Map.Map k String | |
phoneBookToMap xs = Map.fromListWith add xs | |
where add number1 number2 = number1 ++ ", " ++ number2 | |
phoneBookToMap' :: (Ord k) => [(k, String)] -> Map.Map k [String] | |
phoneBookToMap' = Map.fromListWith (++) . map (\ (k,v) -> (k, [v])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment