map :: (a -> b) -> [a] -> [b]
type Trace a = Int -> a
traceMap :: (a -> b) -> (Trace a) -> (Trace b)
type BinTree a = Leaf | Fork a (BinTree a) (BinTree a)
binTreeMap :: (a -> b) -> (BinTree a) -> (BinTree b)
fmap :: (a -> b) -> f a -> f bfmap to satisfy some properties
fmap id = idfmap f . fmap g = fmap (f . g)fmap is also written as (<$>)
newtype T c = T (c -> Int)contramap :: Contravariant f => (a -> b) -> f b -> f aclass Functor f => Applicative (f :: * -> *) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
GHC.Base.liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
{-# MINIMAL pure, ((<*>) | liftA2) #-}
pure :: a -> f a puts the a inside a box<*> :: f (a -> b) -> f a -> f b lets you use operations inside a boxm10, m20 :: Maybe Int
m10 = pure 10
m20 = pure 20
m10 :: Maybe Int
(+) :: Int -> (Int -> Int)
(+) <$> m10 :: Maybe (Int -> Int)
(+) <$> m10 <*> m20 :: Maybe Int
A -> B takes some value in A and gives you something in B.getLine :: IO String
getLine is not a String. Rather it is a recipe that produces a String.putStrLn :: String -> IO ()
putStrLn "hello" is a recipe that produces nothing useful.putStrLn "hello" is the recipe “write ‘hello’ to the console, and do not produce anything”(>>=) :: IO a -> (a -> IO b) -> IO bgetLine :: IO String
putStrLn :: String -> IO ()
echo :: IO ()
echo = getLine >>= putStrLn
addHello :: String -> String
greet = getLine >>= (putStrLn . addHello)addHello :: String -> String
addHello name = "Hello, " + name
greet :: IO ()
greet = getLine >>= \name -> putStrLn (addHello name)
main :: IO () describes what the program does
main = greetIO Cake is like a recipe to produce a Cake. It is not an actual Cake.
IO Cake.IO Cake -> Cake.(<$>)(<*>), pure(>>=)extract :: IO a -> a
IO a, instead you use >>= to channel it to another function.getLine >>=
(\name -> putStrLn ("Hey " ++ name ++ ", you rock!")
putStrLn "Hello, what's your name?" >>=
(\_ -> getLine >>=
(\name -> putStrLn ("Hey " ++ name ++ ", you rock!")
)
)
name <- getLine is translated to getLine >>= \name -> ...main = do
putStrLn "Hello, what's your name?"
name <- getLine
putStrLn ("Hey " ++ name ++ ", you rock!")
import Data.Char
putStrLn "Hello, what's your name?" >>=
(\_ -> getLine >>=
(\name -> let bigName = map toUpper name in putStrLn ("Hey " ++ bigName ++ ", you rock!")
)
)
main = do
putStrLn "Hello, what's your name?"
name <- getLine
let bigName = map toUpper name
putStrLn ("Hey " ++ name ++ ", you rock!")
let or a <->>: a >> b. First do a, then do b. Example putStrLn "Hello" >> putStrLn "Bye".
getLine >> getLine takes two lines from STDIN, ignores the first. See the example below>> implemented?foo = getLine >> getLine
main = do
secondLine <- foo
putStrLn $ "The second line was: " ++ secondLine
yes = putStrLn "Yes" >> yes
yes1 = forever $ putStrLn "Yes"
isPositive = do
n <- read <$> getLine
if (n > 0)
then putStrLn "positive"
else if (n == 0) then putStrLn "zero"
else putStrLn "negative"
See https://github.com/Agnishom/PRGH17/blob/master/tut4/notes.md