2014-02-12 38 views
6

我知道如何使用記錄語法在Haskell,但我有麻煩理解什麼花括號裏面的東西是哈斯克爾記錄語法脫

data PairRecord = PR {foo::Int, bar::String} deriving (Eq,Show) 
x = (PR {foo=1, bar="init"}) 
y= x {foo=23} 
  • 什麼{foo=23}的事情嗎?最後一行看起來好像是對函數x的一個 參數,顯然不是這種情況。
  • 有沒有 我可以用{foo=23}做什麼,除了把它放在 的記錄後?
  • 有沒有正式的方式來解除它,就像我們可以用do表示法做的那樣?

回答

10

該語法稱爲「記錄更新」或「使用字段標籤更新」,並在Section 3.15.3 of the Haskell 2010 report中進行了描述。它可以脫毛。確切的規則在報告中給出。在您的例子中,x {foo = 23}的脫糖是

case x of 
    PR f b -> PR 23 b 
    _  -> error "Update error" 

注意到,該報告使用了被稱爲該公司在section before, 3.15.2, on "Construction using field labels"描述的脫糖「選擇」輔助功能。

+0

所以,你可以desugar x {foo = 23},但是{foo = 23}本身沒有意義,唯一的用法是與x(或其他記錄)結合使用。 –

+1

是的,沒錯。語法'{foo = ...}'只能用於構造,模式匹配或記錄更新,並且只能與其他組件結合使用。它沒有孤立的意義。 – kosmikus

0

你需要的是叫做lenses。但首先你必須安裝包裝鏡頭。

+1

哦,天哪,鏡頭變成了Haskell的jQuery? – Tarmil

+0

儘管我喜歡鏡頭,但這並不能解決問題。這可能是一個好的方面,但它不回答這個問題。 –

+0

@Tarmil:那真是太離譜了...... –

0

通過查看類型:

:t PR 
PR :: Int -> String -> PairRecord 

所以這意味着你需要一個int和一個字符串,以構建一個PairRecord。

現在,在PairRecord的定義,已經定義的訪問:

:t foo 
foo :: PairRecord -> Int 

爲了使用富(如訪問),您需要提供一個PairRecord。你得到一個 爲智力返回值:

foo y 
23 

這意味着,以及單獨foo的已經沒有意義,這個功能需要一個PairRecord。

作爲kosmikus已經指出,語法

y= x {foo=23} 

從現有PairRecord創建y隨設置爲23的整數(與存取器函數的幫助下)。

+0

foo * does *具有明確定義的含義:它是PairRecord到Int的函數。但是,{foo = 23}如果沒有x前面的話就什麼都不是。 –