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