2017-06-01 2 views
2

Ich hatte mit einigen Haskell-Funktionsbeispielen zu tun, die uns unser Ausbilder gegeben hat. Aber ich verstand nicht, diese spezielle Funktion:Wie produziert dieser Code diese Ausgabe?

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

und es produziert [False] als Ausgabe, aber ich verstand nicht, warum. Kann man das bitte im Detail erklären?

Antwort

5

Diese Liste Verständnis besteht aus drei Teilen:

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

Der Generator kann somit aIterierte über eine Liste mit zwei Elementen. Diese Elemente sind [True,False] oder [False,True] (abhängig vom Wert von x). Aber so immer die gleichen Werte (nur die Reihenfolge der Elemente ist unterschiedlich).

Als nächstes wird der Filter Teil in a kommt. Ein Filter enthält die Werte, für die das Prädikat True lautet. Hier ist das Prädikat einfach a: so behält es Konfigurationen, für die a = True. Da True und False für a aufgelistet sind, bedeutet dies, dass wir nur einen Artikel berücksichtigen: der eine, wo aTrue ist.

für diesen Wert, wir ergebennot a. Jetzt ist not True natürlich False. Als Ergebnis werden wir unabhängig vom Wert x (solange es True oder False ist) immer [False] generieren.

So als Ergebnis:

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

Thank you! Wenn also der Yield-Anteil "a" wäre und der Filter "nicht a" wäre, wäre das Ergebnis "[TRUE]' **? Auch warum "Ein Filter behält nur die Werte, für die das Prädikat" True "ist? Es ist eine Regel, denn wenn es nur "a" ist, kam mir zuerst in den Sinn, dass es einen beliebigen Wert haben kann. Kannst du das bitte erklären ** filter ** Teil bitte – Snxby

+0

@Snxby: nein, denn wenn der Filter 'nicht ein' ist, dann wäre nur' a = Falsch' erlaubt, und wir würden also 'a' ergeben und somit würde das wieder passieren Ergebnis in '[False]'. –

+1

@Snxby Sie fragen, warum Listen Verständnis Filter nur Werte beibehalten, wo das Prädikat gibt "True". Je nachdem, welche Frage Sie stellen wollten, gibt es zwei mögliche Antworten. Wenn Sie fragen wollten, "woher wissen Sie, dass dies das Verhalten ist", lautet die Antwort (siehe den Bericht) (https://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-420003.11) . Wenn Sie sich fragen wollten, "warum wurde dieses Verhalten gewählt?", Lautet die Antwort, weil nur einige Elemente einer Liste beibehalten werden müssen, und dies ist ein natürlicher und einfacher Weg, dieses Bedürfnis zu erfüllen. –

0

können Sie auch verstehen mit equational Argumentation.Beginnen Sie mit der Liste Verständnis:

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

Desugar zur Liste Monade:

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

Desugar do Notation:

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

Inline die Definition von >>= für Listen:

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

guard/>>:

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

Inline return:

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

erweitern concatMap g xs-concat (map g xs):

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

Inline map:

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

Beachten Sie, dass if x then [not x] else []-[False] auswertet, wenn x ist True und [] wenn xFalse ist, und dass if not x then [not (not x)] else [] ausgewertet [] wenn x ist True und [False] wenn xFalse ist. Deshalb haben Sie:

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

Und da [False] ++ [] == [] ++ [False] == [False] erhalten Sie:

f x = [False] 
Verwandte Themen