I'm just learning Yesod/Haskell.
In the following code (http://www.yesodweb.com/book/restful-content) there are two things I don't understand (and a subsequent question).
{..} - what does that mean?  (It's a hard term to google for.)person@Person - what does the @ sign do?code:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeFamilies      #-}
import           Data.Text (Text)
import           Yesod
data Person = Person
    { name :: Text
    , age  :: Int
    }
instance ToJSON Person where
    toJSON Person {..} = object
        [ "name" .= name
        , "age"  .= age
        ]
data App = App
mkYesod "App" [parseRoutes|
/ HomeR GET
|]
instance Yesod App
getHomeR :: Handler TypedContent
getHomeR = selectRep $ do
    provideRep $ return
        [shamlet|
            <p>Hello, my name is #{name} and I am #{age} years old.
        |]
    provideJson person
  where
    person@Person {..} = Person "Michael" 28
main :: IO ()
main = warp 3000 App
                For points 1 and 2, I guess you're referring to line
person@Person {..}
The {..} comes from the RecordWildcards extension. Basically it brings in scope all fields of the Person datatype. That's why you can use name and age in the Hamlet template above.
The @ serves as an alias. Everytime you see id@deconstructor_expr you can use id for the entire value which is deconstructed by deconstructor_expr. For example you can have
f (x:a@(y:_)) = a
and a will be the tail of the argument list as long as the list has at least 2 elements (that is f is tail for lists with more than 2 elements).
Without these two, the entire function would have to change to
getHomeR :: Handler TypedContent
getHomeR = selectRep $ do
    provideRep $ return
        [shamlet|
            <p>Hello, my name is #{name'} and I am #{age'} years old.
        |]
    provideJson person
  where
    person = Person "Michael" 28
    name' = name person
    age' = age person
Observe that name and age are functions from the record to the specific field and that means that you have to use other names for the values (the '-ending variables). Also, because we no longer use @ we need separate lines for the person and for the fields.
Another alternative would be
getHomeR :: Handler TypedContent
getHomeR = selectRep $ do
    provideRep $ return
        [shamlet|
            <p>Hello, my name is #{name person} and I am #{age person} years old.
        |]
    provideJson person
  where
    person = Person "Michael" 28
You still need to call the name and age functions.
For point 3, a possibility is to go on IRC on #haskell and ask there. Anyway, the same people from there are here, it's not a bother in asking.
Adding to other answers, for searching for ungooglable syntax use symbolhound.com.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With