2017-06-01 69 views
2

我正在處理一些我們的教師給我們的Haskell函數示例。但我不明白這個特殊的功能:這段代碼如何產生這個輸出?

f x = [not a | a<-[x,not x], a] 

和它產生[False]作爲輸出,但我不明白爲什麼。請詳細解釋一下嗎?

回答

5

這個列表解析出由三個部分組成:

[ not a | a <- [x, not x], a ] 
-- ^yield^generator ^filter 

發生器從而讓a迭代在具有兩個單元的明細表。那些元素是[True,False][False,True](取決於值x)。但是總是有相同的值(只有元素的順序不同)。

下一步過濾部分來自於a。過濾器保留謂詞爲True的值。這裏的謂詞只是a:所以它保留了其中的配置a = True。由於TrueFalsea列舉,這意味着我們將只考慮一個項目:其中aTrue的項目。

這種價值,我們產生not a。現在not True當然是False。因此,無論x(只要它是TrueFalse)的值,我們將始終生成[False]

這樣的結果:

Prelude> let f x = [not a | a<-[x,not x], a] 
Prelude> f True 
[False] 
Prelude> f False 
[False] 
+0

謝謝!所以如果** yield部分是'a'而過濾器不是''結果會是'[TRUE]'**吧?另外爲什麼「一個過濾器只保留謂詞爲」True「的值?這是一條規則,因爲如果它剛剛出現在我腦海裏,那麼它可以是任何價值。你能解釋一下嗎?**過濾**部分請 – Snxby

+0

@Snxby:不是,因爲如果過濾器不是'',那麼只允許'a = False',因此我們會產生'a',因此會再次導致'[False]'。 –

+1

@Snxby你問爲什麼列表理解過濾器只保留謂詞給出'真'的值。這裏有兩個可能的答案,取決於你打算問什麼問題。如果你打算問「你怎麼知道這是行爲」,答案是[查看報告](https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11) 。如果你打算問「爲什麼選擇這種行爲」,答案是因爲只保留列表中的某些元素是一種常見的需求,而這是解決該需求的一種自然而簡單的方法。 –

0

您也可以用等式推理明白這一點。先從列表理解:

f x = [not a | a <- [x, not x], a] 

Desugar到列表單子:

f x = do 
    a <- [x, not x] 
    guard a 
    pure (not a) 

Desugar do符號:

f x = [x, not x] >>= \ a -> guard a >> return (not a) 

內嵌的>>=對列表的定義:

f x = concatMap (\ a -> guard a >> return (not a)) [x, not x] 

內嵌guard/>>

f x = concatMap (\ a -> if a then return (not a) else []) [x, not x] 

內嵌return

f x = concatMap (\ a -> if a then [not a] else []) [x, not x] 

展開concatMap g xsconcat (map g xs)

f x = concat (map (\ a -> if a then [not a] else []) [x, not x]) 

內嵌map

f x = concat 
    [ if x then [not x] else [] 
    , if not x then [not (not x)] else [] 
    ] 

注意if x then [not x] else []評估爲[False]如果xTrue[]如果xFalse,那if not x then [not (not x)] else []評估爲[]如果xTrue[False]如果xFalse。因此,你必須:

f x = if x then [False] ++ [] else [] ++ [False] 

而且,由於[False] ++ [] == [] ++ [False] == [False],您可以:

f x = [False] 
相關問題