Updates list in haskell to remove duplication
It is better to use records instead of tuples here:

data Rating = Rating
  { user :: String
  , rate :: Int
  } deriving Show

data Film = Film
  { title    :: String
  , director :: String
  , year     :: Int
  , ratings  :: [Rating]
  } deriving Show


Thus you get self documenting code and all of pull* functions for free (for each field compiler generates accessor function with the same name).

This also leads to more concise implementation of other functions:

-- Find films by name
getFilm :: String -&gt; [Film] -&gt; [Film]
getFilm search = filter ((== search) . title)


Note that in Haskell there is no single element tuple, so parentheses around Film are redundant ([Film] but not [(Film)]).

newRating :: Rating -&gt; [Rating] -&gt; [Rating]
newRating r = (r :) . filter ((/=user r) . user) 


I switched arguments in newRating because this allows to define function more concisely and it is also correlates with update/insert from Data.Map: they have collection as a last argument.

Now it is possible to skip directly to rateMovie and implement it in couple of lines:

rateMovie :: String -&gt; Rating -&gt; [Film] -&gt; [Film]
rateMovie mTitle nRating database
  = [m {ratings = newRating nRating (ratings m)} | m &lt;- matchingMovies]
  ++ database'
  where
    (matchingMovies, database') = partition ((==mTitle).title) database


(Btw, why "movie"? we were talking about "films" all the way.)

I'm using partition from Data.List to extract matching movie(s) from database.

Also there is funny syntax I'm using to update movies:

m {ratings = ...}


You can read more about it here.

And of course it is better to use Data.Map instead of simple lists if the code is full of lookups.