Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:functors [2021/04/19 11:11]
lfa [6. Functors, Foldables]
pp:functors [2021/04/21 15:51] (current)
alexandru.rait Changed 6 to 7 in title
Line 1: Line 1:
-====== ​6. Functors, Foldables ======+====== ​7. Functors, Foldables ======
  
 Functors are data types over which we can ''​map''​ a function (that is, apply a function on each element while keeping the overall structure). You've already encountered a Functor, namely haskell lists. For historical reasons, ''​map''​ only works on lists (''​map :: (a -%%>%% b) -%%>%% [a] -%%>%% [b]''​),​ but there exists a more general function ''​fmap''​ (''​fmap :: (Functor f) =%%>%% (a -%%>%% b) -%%>%% f a -%%>%% f b''​). Functors are data types over which we can ''​map''​ a function (that is, apply a function on each element while keeping the overall structure). You've already encountered a Functor, namely haskell lists. For historical reasons, ''​map''​ only works on lists (''​map :: (a -%%>%% b) -%%>%% [a] -%%>%% [b]''​),​ but there exists a more general function ''​fmap''​ (''​fmap :: (Functor f) =%%>%% (a -%%>%% b) -%%>%% f a -%%>%% f b''​).
Line 7: Line 7:
 <code haskell> <code haskell>
 class Functor f where class Functor f where
-    fmap :: (a -%%>%% b) -%%>%% f a -%%>%% f b+    fmap :: (a -> b) -> f a -> f b
 </​code>​ </​code>​
     ​     ​
Line 86: Line 86:
 </​code>​ </​code>​
  
-Now our functions work and can handle the empty list without throwing an exception. However, it should be obvious that we now need to change any ''​Int -> a''​ function we want to apply on our result to a ''​Maybe Int -> Maybe a''​ function, which seems like a lot of work. Plus the change will be as dull in all cases:+Now our functions work and can handle the empty list without throwing an exception. However, it should be obvious that we now need to change any ''​Int -%%>%% a''​ function we want to apply on our result to a ''​Maybe Int -%%>%% Maybe a''​ function, which seems like a lot of work. Plus the change will be as dull in all cases:
  
   - if we get a ''​Nothing'',​ we return a ''​Nothing''​   - if we get a ''​Nothing'',​ we return a ''​Nothing''​
   - if we get a ''​Just'',​ we unpack it, do with it what the function did originally, then repack it in a ''​Just''​.   - if we get a ''​Just'',​ we unpack it, do with it what the function did originally, then repack it in a ''​Just''​.
  
-It would be great if we could just have a function which does this transformation for us. And we do. Remember currying and how multiple-argument functions actually take on argument and return another function and so on. Thus we can reinterpret ''​fmap'''​s signature as: ''​(a -> b) -> (f a-> (f b)''​. That is: it takes a function from ''​a''​ to ''​b''​ and returns a function from a functor ''​a''​ to a functor ''​b''​. Set the functor ''​f''​ to ''​Maybe''​ and that'​s ​ it!+It would be great if we could just have a function which does this transformation for us. And we do. Remember currying and how multiple-argument functions actually take on argument and return another function and so on. Thus we can reinterpret ''​fmap'''​s signature as: ''​(a -%%>%% b) -%%>%% (f a -%%>%% f b)''​. That is: it takes a function from ''​a''​ to ''​b''​ and returns a function from a functor ''​a''​ to a functor ''​b''​. Set the functor ''​f''​ to ''​Maybe''​ and that'​s ​ it!
  
 <code haskell> <code haskell>