ptkato
ptkato

Reputation: 708

Type mismatch between FileInfo and Text

I'm following this tutorial and got a type mismatch error while creating the function who builds the form.

I don't know what import I should post here, so there's all:

import Control.Applicative
import Data.Text (Text, unpack)
import qualified Data.Text as T
import qualified Data.ByteString.Lazy as DBL
import Data.Conduit
import Data.Conduit.List (consume)
import Yesod
import Yesod.Static
import Yesod.Form.Bootstrap3
import Data.Time (UTCTime, getCurrentTime)
import Control.Monad.Logger (runStdoutLoggingT)
import Database.Persist
import Database.Persist.Sqlite
import System.FilePath
import System.Directory (removeFile, doesFileExist)

And the code:

data Page = Page

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Image
        filename Text
        description Textarea
        date UTCTime
        deriving Show
|]

instance Yesod Page where
type Form a = Html -> MForm Handler (FormResult a, Widget)

uploadForm :: Form Image
uploadForm = renderDivs $ Image
    <$> fileAFormReq (bfs ("Image" :: Text)) -- error line
    <*> areq textareaField (bfs ("Description" :: Text)) Nothing
    <*> lift (liftIO getCurrentTime)

Couldn't match type FileInfo with Text
-- Expected type: AForm Handler Text
------ Actual type: AForm Handler FileInfo …

I really don't think there's, actually, an error within the Yesod's wiki on GitHub, I guess it's in the code of mine, but I couldn't figure it out.

Upvotes: 1

Views: 182

Answers (1)

ErikR
ErikR

Reputation: 52059

I'm sure the Yesod API has changed since the example was written.

The problem is that your filename field for the Image type is a Filename, but fileAFormReq now returns a FileInfo (docs).

Try changing the definition of Image to:

Image
    fileinfo FileInfo
    description Textarea
    date UTCTime
    deriving Show

A FileInfo value has this structure (docs):

FileInfo     
  fileName :: !Text
  fileContentType :: !Text
  fileSourceRaw :: !(Source (ResourceT IO) ByteString)
  fileMove :: !(FilePath -> IO ())

so use the fileName accessor to get at the file name of a FileInfo.

Upvotes: 4

Related Questions