Search code examples
sqlitehaskelliomonads

Haskell transfer between monadic functions


Feel I am never going to fully grasp Haskell now. Two functions: one that counts records in a SQlite DB, so it can produce incremental IDs (checkUniqueID). The other one to make the records, calling on checkUniqueID. I just need the value over to taskEntry as an Int. I guess I am missing the knowledge to stay in the monadic realm. Code below.

-- checkUniqueID :: IO ()
checkUniqueID = do
  conn <- open "taglist.db"
  len <- query_ conn "SELECT (id) FROM task" :: IO [Only Int]
  let showLength = Data.List.length $ len
  close conn
  return (showLength + 1) -- for testing purposes

-- fieldnames: id, task, date_in, date_out
taskEntry :: IO ()
taskEntry = do
      putStrLn "Provide task and date due: "
      let taskIDInt = checkUniqueID -- issue here!
      task <- getLine
      date_out <- getLine
      let date_in = "today"
      conn <- open "taglist.db"
      execute conn "INSERT INTO task (id, task, date_in, date_out) VALUES (?,?,?,?)"
            (taskIDInt :: Int , task :: String , date_in :: String , date_out :: String)
      close conn
      return ()

Solution

  • First, checkUniqueID returns an Int, so its type should be IO Int, not IO ():

    checkUniqueID :: IO Int
    

    Second, within the do notation, the left arrow <- is what binds result of a monadic function to a name. You're already using it with getLine, so I'm not entirely sure why you would fail to use it with checkUniqueID as well:

    taskIDInt <- checkUniqueID