haskell-21

elemIndex

Here is an example of how it should behave

elemIndex 'a' "abcd" = Just 0
elemIndex 'b' "abcd" = Just 1
elemIndex 1 [2, 3, 4, 1] = Just 3
elemIndex 'x' "abcd" = Nothing

myFunc : a Mystery Function

Consider the function myFunc below.

myFunc _ [] = []
myFunc x (f:fs) = f x : myFunc x fs
-- Expression 1
myFunc 2 [(+1), (+2), (+3)]
-- Expression 2
myFunc (+1) [1,2,3]

Recall that if a type constructor f :: * -> * is instance of Applicative, then we have two functions:

class Applicative f where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b
instance Applicative [] where
    pure :: a -> [a]
    pure = undefined
    (<*>) :: [a -> b] -> [a] -> [b]
    (<*>) = undefined

In order to make sure that your definitions are correct, you should make sure that the following identities hold:

pure id <*> v = v    
pure f <*> pure x = pure (f x) 
u <*> pure y = pure (\f -> f y) <*> u
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)

(Remember that id :: a -> a is defined as id x = x and (.) is function composition where (f .g ) x is defined as f (g x).)

You don’t need to give a proof of these identities (or write anything to justify that they hold). Also, unless you pick a degenerate definition of the functions above, these should almost automatically hold.

Unfolding

Carefully try to understand the following function

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
unfoldr f b = case f b of
    Nothing -> []
    Just (x, b') -> x : unfoldr f b'

(Int -> ) is a Functor

Consider type Trace a = Int -> a.

instance Functor Trace where
  fmap :: (a -> b) -> Trace a -> Trace b
  fmap = undefined

Recall that the identity id :: a -> a and the composition function (.) :: (b -> c) -> (a -> b) -> a -> c is defined as follows.

id :: a -> a
id x = x
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)

Playing with IO

Recall that getLine :: IO String and putStrLn :: String -> IO (). Suppose that mysteryAction :: String -> IO Int

myAction1 s = do
    getLine
    putStrLn s
    mysteryAction s

myAction2 = do
    myAction1 "ABC"
    getLine

myAction3 = do
    s <- myAction2
    myAction1 s
    putStrLn s

myAction4 = do
    myAction3
    pure ()

myAction5 = do
    s <- myAction2
    myAction1 s
    putStrLn s
    s <- myAction2