Applicative Functor Strikes Back!

Ville Tirronen

27.10.2011

Muistutuksia & Huomioita

http://www.youtube.com/watch?v=MhcW6VYjP_4 Ryhmät ------

Yousource

Harjoitustehtävistä

Miksi tehtiin Jasennin?

Harjoitustehtävistä

Miksi tämä tuntui vaikealle?

Ongelmanratkaisustrategioita

Mitä tehdä jos ei vain etene?

  1. KÄYTÄ SUTTUPAPERIA/EDITORIA
  2. Kirjoita paperille jokaisen muuttujan tyyppi.
  3. Etsi kaikki mahdolliset tuntemasi funktiot ja määritelmät, jotka koskevat näitä tyyppejä.
  4. Katso kaikki polymorfisetkin funktiot, jos ne saisi toimimaan jollekin näistä tyypeistä?
  5. Mitä seuraisi jos jos kutsuisit jotain noista funktioista?
    • Jos saat funktion, kutsu sitä
    • Jos saat tietotyypin, avaa se case:lla
    • Jos saat arvon, voitko kutsua sillä jotain funktiota?
  6. Kirjoita jotain.
  7. Siisti vasta lopuksi.

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Asiaan liittyvät määritelmät

data Jasennin a = J (String -> Maybe (a,String))

class Functor f where
fmap :: (a -> b) -> (f a -> f b)

J :: (String -> Maybe (a,String)) -> Jasennin a

ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))
ajaJasennin (J a) = a

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Aluksi

instance Functor Jasennin where 
fmap f = ?

Tiedetään, että

? :: (Jasennin a -> Jasennin b)
f :: (a->b)
J :: (String -> Maybe (a,String)) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Tehdään funktio

instance Functor Jasennin where 
fmap f = \a -> ??

Tiedetään, että

??   :: Jasennin b
f :: (a->b)
a :: Jasennin a
J :: (String -> Maybe (a,String)) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Korjataan nimi vastaamaan tyyppiä

instance Functor Jasennin where 
fmap f = \jasennin -> ??

Tiedetään, että

??        :: Jasennin b
f :: (a->b)
jasennin :: Jasennin a
J :: (String -> Maybe (a,String)) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Mitä saisimme ??:n paikalle sopivan arvon?

instance Functor Jasennin where 
fmap f = \jasennin -> ??

Tiedetään, että

??          :: Jasennin b
f :: (a->b)
jasennin :: Jasennin a
J :: (String -> Maybe (a,String) -> Jasennin
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))

Ainoa mahdollisuus lienee funktio J.

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Osaisimmeko kutsua J:tä?

instance Functor Jasennin where 
fmap f = \jasennin -> J (???)

Tiedetään, että

???         :: (String -> (Maybe b,String)
f :: (a->b)
jasennin :: Jasennin a
J :: (String -> Maybe (a,String) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Mistä saadaan funktioita? Lambdalla!

instance Functor Jasennin where 
fmap f = \jasennin -> J (\string -> ????)

Tiedetään, että

????        :: Maybe (b,String)
string :: String
f :: (a->b)
J :: (String -> Maybe (a,String) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))
jasennin :: Jasennin a

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Tiedot eivät riitä!

Ainoa tässä vaiheessa ainoa sovellettava funktio on ajaJasennin. Lisätään se tiedettyjen asioiden joukkoon:

ajaJasennin jasennin string :: Maybe (a,String)
???? :: Maybe (b,String)
string :: String
f :: (a->b)
J :: (String -> Maybe (a,String) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))
jasennin :: Jasennin a

Osaisimmeko kirjoittaa apufunktion, joka muuttaa Maybe (a,String):n Maybe (b,String)ksi?

Esimerkki -- Koodataan apufunktio

Ekana pattern matching

apufunktio :: Maybe (a,String) -> Maybe (b,String)
apufunktio Nothing = ??
apufunktio (Just (a,str)) = ???

Tiedetään

str      :: String
f :: (a->b)
a :: a
?? :: Maybe (b,String)
??? :: Maybe (b,String)

Esimerkki -- Koodataan apufunktio

Nothing on usein Nothing

apufunktio :: Maybe (a,String) -> Maybe (b,String)
apufunktio Nothing = Nothing
apufunktio (Just (a,str)) = ???

Tiedetään

Nothing  :: Maybe (b,String)
str :: String
f :: (a->b)
a :: a
??? :: Maybe (b,String)

Esimerkki -- Koodataan apufunktio

Mitähän f a on?

Nothing  :: Maybe (b,String)
str :: String
f :: (a->b)
a :: a
f a :: b
Just :: b -> Maybe b
??? :: Maybe (b,String)
apufunktio :: Maybe (a,String) -> Maybe (b,String)
apufunktio Nothing = Nothing
apufunktio (Just (a,str)) = Just (f a, str)

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Lisätietoja!

Katsotaanpa mitä nyt olemme saaneet selville:

????        :: Maybe (b,String)
apufunktio :: Maybe (a,String) -> Maybe (b,String)
string :: String
f :: (a->b)
J :: (String -> Maybe (a,String) -> Jasennin a
ajaJasennin :: Jasennin a -> (String -> Maybe (a,String))
jasennin :: Jasennin a
ajaJasennin jasennin string :: Maybe (a,String)

Nyt meillä on funktio, josta tulee Maybe (b,String) ja me osaamme kutsua sitä!

instance Functor Jasennin where 
fmap f = \jasennin -> J (\string -> apufunktio (ajaJasennin jasennin string))

Esimerkki -- Koodataan Functor instanssi jäsentimelle

Lopputulos

instance Functor Jasennin where 
fmap f = \jasennin -> J (\string -> apufunktio (ajaJasennin jasennin string))
where
apufunktio Nothing = Nothing
apufunktio (Just (a,str)) = Just (f a, str)

Eli osasimme mitään tietämättä tehdä funktorin. Lisäksi, jos jatkamme, voimme siistiä koodin tosi nätiksi.

Live-Demo?

Haluatteko toisen esimerkin?

Esimerkkivastaukset

Ratkaisu A

Ratkaisu B

Ryhmien pohdintaa

Kysymyksiä?

Huomioita?

Ensiviikon harjoitukset

Kertausviikko