7

我只是在学习 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
4

3 回答 3

13

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

person@Person {..}

来自扩展{..}RecordWildcards基本上,它引入了数据类型的所有字段Person。这就是您可以在上面的 Hamlet 模板中使用name和的原因。age

@用作别名。每次你看到id@deconstructor_expr你都可以使用id被解构的整个值deconstructor_expr。例如你可以有

f (x:a@(y:_)) = a

只要列表至少有 2 个元素(即具有超过 2 个元素的列表),它a就是参数列表的 。tailftail

如果没有这两个,整个功能将不得不更改为

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

您仍然需要调用nameandage函数。

对于第 3 点,一种可能性是在#haskell 上进行 IRC 并在那里询问。不管怎样,这里的人都是一样的,问起来也不麻烦。

于 2013-09-24T10:38:19.933 回答
7

添加到其他答案,用于搜索 ungooglable 语法使用symbolhound.com

于 2013-09-24T11:25:52.320 回答
2

{..}将记录解压缩为变量。在您的情况下,它定义了nameand age@在模式匹配中获取整个值,因此 inperson@Person {..}person是原始Person值。

于 2013-09-24T10:38:53.290 回答