What I need to do is build a type of database. Firstly have a few questions, whether what I have done it right...and how to do something else.

This is my algebraic type for the database (correct me if its wrong)

data Film = Film String String Int String

with this as the data.

testDatabase :: [Film]
testDatabase = [("Casino Royale", "Martin Campbell",2006, "Garry, Dave, Zoe")]

the last set of strings are the fans to the film. I want to be able to add a new fan, but not sure how to specifically insert it to there

this is what I have so far:

becomeFan :: String -> String -> [Film] -> [Film]
becomeFan = do putStr "Which film are you a fan of: "
filmTitle <- getLine
do putStr "What is your name: "
fanName <- getLine
(if filmTitle == filmName then fanName : [Film])

Dani AI

Generated

Two clear fixes will make this approach work. As noted, the literal you wrote is a tuple, not a Film value; construct Film values (record syntax helps). Also store fans as a list of strings ([String]) rather than encoding them into a single comma string. Keep pure data-manipulation functions separate from IO: write a pure updater for the database, and call that from an IO action that reads user input.

A compact, practical layout (record syntax plus pure helpers):

data Film = Film
  { title    :: String
  , director :: String
  , year     :: Int
  , fans     :: [String]
  } deriving (Show, Eq)

addFanToFilm :: String -> Film -> Film
addFanToFilm newFan f = f { fans = newFan : fans f }

addFanToDB :: String -> String -> [Film] -> [Film]
addFanToDB filmTitle newFan = map update
  where
    update f
      | title f == filmTitle = addFanToFilm newFan f
      | otherwise            = f

When reading from the console, the action must carry IO. A thin IO wrapper calls the pure updater (do not declare a pure signature and then use do in it):

promptAddFan :: [Film] -> IO [Film]
promptAddFan db = do
  putStrLn "Film title?"
  fTitle <- getLine
  putStrLn "Your name?"
  name <- getLine
  return (addFanToDB fTitle name db)

Practical cautions: matching on raw title strings is brittle (case and whitespace matter) — normalize strings or use unique IDs. Prevent duplicate names with nub or use a Set. For persistence, derive Read/Show for quick prototypes or switch to JSON (aeson) for robust storage. For syntax and further reference, the Haskell report is authoritative: Haskell 2010 Report.

What I need to do is build a type of database. Firstly have a few questions, whether what I have done it right...and how to do something else.

This is my algebraic type for the database (correct me if its wrong)

data Film = Film String String Int String

with this as the data.

testDatabase :: [Film] 
testDatabase = [("Casino Royale", "Martin Campbell",2006, "Garry, Dave, Zoe")]

That's broken. The expression ("Casino Royale", "Martin Campbell", 2006, "Garry, Dave, Zoe") is of type (String,String,Int,String) if we say that 2006 is of type Int. You want an expression of type Film. You need to use the Film data constructor instead of a tuple.

the last set of strings are the fans to the film. I want to be able to add a new fan, but not sure how to specifically insert it to there

If you're encoding information into a String by separating words with commas, you'd be better off using a [String] in its place.

this is what I have so far:

becomeFan :: String -> String -> [Film] -> [Film]
becomeFan = do putStr "Which film are you a fan of: "
filmTitle <- getLine
do putStr "What is your name: "
fanName <- getLine
(if filmTitle == filmName then fanName : [Film])

You should review some of the basics of how Haskell works and get comfortable with things using simpler problems.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.