Skip to content

Instantly share code, notes, and snippets.

@jayunit100
Created April 2, 2015 13:18
Show Gist options
  • Save jayunit100/b35730e955d90a365f6a to your computer and use it in GitHub Desktop.
Save jayunit100/b35730e955d90a365f6a to your computer and use it in GitHub Desktop.
haskell all the things
import Data.Ord
import Data.List
-- type classe = contructor + arguments.
data BookInfo = Book Int String [String]
deriving (Show)
data MagazineInfo = Magazine Int String [String]
deriving (Show)
-- Now use type aliases.
type CustomerID = Int
type ReviewBody = String
-- A book review consists of a BookInfo object, and a CustomerID, and a String.
data BookReview = BookReview BookInfo CustomerID String
data BetterReview = BetterReview BookInfo CustomerID ReviewBody
type BookRecord = (BookInfo, BookReview)
type CardHolder = String
type CardNumber = String
type Address = [String]
-- test 1 test 2 ttest
data BillingInfo = CreditCard CardNumber CardHolder Address
| CashOnDelivery
| Invoice CustomerID
deriving (Show)
-- file: ch01/WC.hs
-- lines beginning with "--" are comments.
main2 = interact wordCount
where wordCount input = show (length (lines input)) ++ "\n"
add a b = a + b
lastButOne xs = if null (tail (tail xs))
then head xs
else lastButOne (tail xs)
-- isOdd
isOdd n = mod n 2 == 1
-- myDrop function.
myDrop n xs = if n <= 0 || null xs
then xs
else myDrop (n - 1) (tail xs)
-- Example exersizes of
-- maybe.hs
main = putStrLn "ASDF"
data Cartesian2D = Cartesian2D Double Double
deriving (Eq, Show)
data Polar2D = Polar2D Double Double
deriving (Eq, Show)
type Vector = (Double, Double)
data Shape = Circle Vector Double
| Poly [Vector]
data Roygbiv = Red
| Orange
| Green
| Blue
| Indigo
| Violet
deriving (Eq, Show)
third (a, b, c) = c
-- Notice that you can only call complicate with perfect args. anything off and you get nonexhaustive error
complicated (True, a , x:xs, 5) = (a, x)
xCoord ( Cartesian2D x y ) = x
yCoord ( Cartesian2D x y ) = y
-- xCoord ( x _ ) = x --- this fails... ?
yCoord2 x _ y = y
-- Cons is not a keyword. As an example of why, look at the List2 implementation below...
data List a = Cons a (List a)
| Nil
deriving (Show)
-- Cons2 is an arbitrary Constructor name. It takes an element 'aa', and a list of
-- aa's. Note that aa is a type . Just the same that we have "data Book xx = BookConstructor xx Int
-- Where the "xx" is any type, and is generic.
data List2 aa = Cons2 aa (List2 aa)
| Nil2
deriving (Show)
data Tree a =
Node a (Tree a) (Tree a)
| Empty
deriving (Show)
-- Functions and types
add2 :: Integer -> Integer -> Integer
add2 x y = x+y
-- Maybe and Just.
-- Here we define a bijection where
-- we intraconvert lists (of length 1)
-- with maybe. If list length != 1, nil.
maybe2List (Just head) = [head]
maybe2List Nothing = []
list2Maybe (first:rest) =
if null rest then Just first
else Nothing
maybe2List2 :: Maybe a -> [a]
maybe2List2 x = case x of
(Just xx) -> [xx]
Nothing -> []
-- Tree : first constructor is
-- called "node". It takes two trees.
data Tree2 a =
Node2 a (Maybe (Tree2 a)) (Maybe (Tree2 a))
deriving (Show)
-- Three ways to find the nth element.
-- nth :: [a] -> n -> Maybe a
test22 =
if 1==2 then 2
else if 2==3 then 3
else 4
nth1 [] n = Nothing
nth1 (x:xs) n =
if n==1 then Just x
else if n>1 then nth1 xs (n-1)
else Nothing
-- nth [1,2,3] 2 -> 2
nth2 [] n = Nothing
nth2 (x:xs) n | n<0 = error "non neg"
| n<1 = Nothing
| n==1 = Just x
| n>1 = nth2 xs (n-1)
-- lend amount balance = let res = 100 in ( newBalance = balance - amount in if balance < res then Nothing else Just newBalance)
-- notice that a can be anything and is unused.
quux a = (let a = "foo"
in a ++ "eek!")
-- pluralize "a b" [1] -> [1 a, 1 b]...
pluralise :: String -> [Int] -> [String]
pluralise word counts = map myfunc counts
-- pattern matching function defined here.
where myfunc 0 = "Nothing"
myfunc 1 = "1 " ++ word
myfunc n = show n ++ " " ++ word ++ "s"
-- show gives stringified n.
-- fromMaybe 1 (Just 1) -> Just 1
-- fromMaybe 1 (Nothing) -> Nothing
fromMaybe defval wrapped =
case wrapped of
Nothing -> defval
Just value -> value
-- xlength [1,2] -> 2
-- xlength [] -> 0
xlength :: [x] -> Int
xlength [] = 0
xlength (head:tail) = 1 + xlength(tail)
xSum :: [Int] -> Int
xSum [] = 0
xSum (head:tail) = head + xSum tail
-- xMean [1,2,3] -> 2
-- This fails due to type errors.
-- WIP jayunit100h: try, xMean l = xSum l / fromIntegral (xlength l)???
-- 1) Note that replaceing "div" with "/" fails
xMean :: [Int] -> Int
xMean [] = 0
xMean l = div (xSum l) (xlength l)
rev :: [Int] -> [Int] -> [Int]
rev [] [] = []
rev [x] l = x:l
rev (x:xs) base | null (tail xs) = x2:x:base
| otherwise = rev (tail xs) (x2:x:base)
where x2 = head xs
example2 = "another where var.. just for example"
-- abc -> abc + cba
-- xa
pal :: [Int] -> [Int]
pal xx = xx ++ rev xx []
isPal :: [Int] -> Bool
isPal x = (rev x []) == x
lenh x = length x
xsortLists :: [[a]] -> [[a]]
xsortLists l = sortBy (comparing length) l
-- "," , ["cat","dog"] --> [ "cat", "," , "dog" ]
-- [[a]] means [String]
-- xisp "c" ["cat","dog"] why does this fail?
xisp :: a -> [[a]] -> [a]
xisp _ (x:[]) = x
xisp s (x:y:xs) = (x ++ [s] ++ y ++ (xisp s xs))
xisp2 :: Char -> [String] -> String
xisp2 x (y:ys)
| (null ys) = y
| otherwise = y ++ [x] ++ (xisp2 x ys)
height :: Tree t -> Int
-- why are the parens below required?
height (Node v left right) = 1 + ( max ( height left ) ( height right ) )
height Empty = 0
data Dir = Left
| Right
| Straight
deriving (Show)
turn :: Cartesian2D -> Cartesian2D -> Cartesian2D -> Dir
-- COMPILE FAILS !!! Why?
turn a b c =
let
xab = (xCoord a) - (xCoord b)
xbc = (xCoord b) - (xCoord c)
yab = (yCoord a) - (yCoord b)
ybc = (yCoord b) - (yCoord c)
in
if ( xbc < 0 ) then Main.Left
else if ( xbc > 0 ) then Main.Right
else Main.Straight
-- Generate a list of cartesian2D points.
-- we force it to be multiple of 3 for the exersize in ch3 of rwh
cartset :: [(Double,Double,Double,Double,Double,Double)] -> [Cartesian2D]
cartset ((a,b,c,d,e,f):pts) = (Cartesian2D a b):(Cartesian2D c d):(Cartesian2D e f):(cartset pts)
cartset [] = []
-- compile fails not sure why?
directions :: [Cartesian2D] -> [ (Maybe Dir) ]
directions (a:b:c:[]) = [(Just (turn a b c))]
directions [] = [Nothing]
directions (a:b:[]) = [Nothing] -- fail, 2 elements
directions (a:[]) = [Nothing] -- fail, 1 element
directions (a:b:c:xs) = (directions (a:b:c:[]))++(directions xs)
splitLines :: String -> [String]
splitLines [] = []
splitLines cs =
let (li,lis) = break isLineTerminator cs
in li : case lis of
('\r':'\n':rest) -> splitLines rest
('\r':rest) -> splitLines rest
('\n':rest) -> splitLines rest
_ -> []
isLineTerminator c = c == '\r' || c == '\n'
func1 = "funk" `isInfixOf` "sonic youth"
func2 = [1] `isInfixOf` [9,1,8]
-- [1,2] -> 1
safeHead x = case x of
[] -> Nothing
h:xs -> h
-- [1,2,3] -> [2,3]
safeTail x = case x of
[] -> Nothing
h:xs -> Just xs
-- [1,2,3] -> 3
safeLast x = case x of
[] -> Nothing
b -> last b
-- [1,2,3] -> [1,2]
safeInit x = case x of
[] -> Nothing
b:[] -> Just [b]
b:c -> Just (init (b:c))
addAlways x _ = 10
-- splitWith
-- [1,2,1,4,4] -> [[1],[2,1],[4,4]]
splitWith :: [a] -> (a -> Bool) -> [a] -> [[a]]
splitWith curr _ [] = [curr]
splitWith curr f [x] = [ (curr++[x]) ]
-- todo , have to figure out how to lend the proper acuumulator list (1st arg).
-- right now the list type doesnt match what is being recursed.
splitWith curr f (l:rem) | (f l) == True = [(curr++[l])] ++ (splitWith [] f rem)
| otherwise = splitWith (curr++[l]) f rem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment