Skip to content

Instantly share code, notes, and snippets.

@MiyamonY
Created February 26, 2015 06:00
Show Gist options
  • Save MiyamonY/987e78242f1a84246faa to your computer and use it in GitHub Desktop.
Save MiyamonY/987e78242f1a84246faa to your computer and use it in GitHub Desktop.
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