我只是在学习Yesod / Haskell。
在下面的代码(http://www.yesodweb.com/book/restful-content)中有两件我不理解的事情(以及随后的问题)。
{..}
- 这是什么意思? (对谷歌而言,这是一个艰难的术语。)person@Person
- @
签到了什么?代码:
{-# 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
答案 0 :(得分:13)
对于第1点和第2点,我猜你是指行
person@Person {..}
{..}
来自RecordWildcards
扩展程序。基本上它会为Person
数据类型的所有字段带来范围。这就是为什么你可以在上面的哈姆雷特模板中使用name
和age
。
@
用作别名。每当您看到id@deconstructor_expr
时,您都可以使用id
获取由deconstructor_expr
解构的整个值。例如,您可以拥有
f (x:a@(y:_)) = a
和a
将是参数列表的tail
,只要该列表至少有2个元素(f
为tail
,对于超过2个元素)。
如果没有这两个,整个功能必须改为
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
观察name
和age
是从记录到特定字段的函数,这意味着您必须使用其他名称作为值('
- 结束变量)。另外,由于我们不再使用@
,因此person
和字段需要单独的行。
另一种选择是
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
您仍然需要调用name
和age
函数。
对于第3点,有可能在#haskell上进行IRC并在那里问问。无论如何,来自那里的人都在这里,问起来并不是很麻烦。
答案 1 :(得分:7)
添加其他答案,搜索不可插入的语法时使用symbolhound.com。
答案 2 :(得分:2)
{..}
将记录解压缩到变量中。在您的情况下,它定义name
和age
。 @
在模式匹配中获取整个值,因此在person@Person {..}
中,person
将是原始Person
值。