Haskell语法:{..}和@的含义

fad*_*bee 7 haskell yesod

我只是在学习Yesod/Haskell.

在下面的代码(http://www.yesodweb.com/book/restful-content)中有两件我不理解的事情(以及随后的问题).

  1. {..}- 那是什么意思?(对谷歌而言,这是一个艰难的术语.)
  2. person@Person- @标志做什么?
  3. 有没有办法可以找到不可编辑的Haskell语法的答案,而不会在StackOverflow上烦扰你们?

码:

{-# 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
Run Code Online (Sandbox Code Playgroud)

Mih*_*eac 13

对于第1点和第2点,我猜你指的是线

person@Person {..}
Run Code Online (Sandbox Code Playgroud)

{..}来自RecordWildcards延伸.基本上它带来了Person数据类型的所有字段的范围.这就是为什么你可以使用nameage上面的哈姆雷特模板.

@作为的别名.每当你看到id@deconstructor_expr你可以使用id被解构的整个价值deconstructor_expr.例如,你可以拥有

f (x:a@(y:_)) = a
Run Code Online (Sandbox Code Playgroud)

并且a将成为tail参数列表的,只要该列表具有至少2个元素(即ftail对于具有多于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
Run Code Online (Sandbox Code Playgroud)

观察它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
Run Code Online (Sandbox Code Playgroud)

你仍然需要调用nameage函数.

对于第3点,有可能在#haskell上进行IRC并在那里询问.无论如何,来自那里的人都在这里,问起来并不是很麻烦.


Nik*_*kov 7

添加到其他答案,搜索不可插入的语法使用symbolhound.com.