2017-07-19 2 views
0

J'ai la fonction qui retourne True si le nombre n est le résultat de l'application ou à l'bitwise séquence de xs:FOLDR appliquée à un seul argument

checkBits xs n = not $ null $ filter (==n) $ map (foldr (.|.) zeroBits) (subsequences xs)

Maintenant, la chose que je ne pas obtenir est que le foldr est donné (.|.) et zeroBits, mais n'ai-je pas besoin d'un autre argument pour foldr. Comme je comprends la fonction de foldr, vous l'appliquez à une fonction, qui est dans ce cas (.|.), à une « valeur de départ », que je suppose est zeroBits, mais quid du t a, qui est mentionné dans:

Prelude>:t foldr foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

Y at-il quelque chose qui me manque? Le code ci-dessus fonctionne d'ailleurs comme il se doit.

+3

Haskell n'exige pas que vous fournissiez tous les arguments en même temps. Si vous ne fournissez que les deux premiers, vous appliquez_partiellement la fonction, et le résultat est une autre fonction qui veut les deux derniers. C'est une caractéristique omniprésente de Haskell, non limitée à 'foldr'. –

+3

Essayez de demander à GHCI le type de 'foldr (. |.) ZeroBits' aussi: puisque c'est apparemment une expression valide, elle doit avoir un certain type, n'est-ce pas? Que pensez-vous que ce type signifie? Comment a-t-il obtenu ce type? – amalloy

+0

Oh, je ne le savais pas. Ça a l'air d'être une fonctionnalité sympa! Merci je l'ai eu ! – IPiiro

Répondre

1

foldr avec un argument "manquant" renvoie une fonction qui prend un seul argument (celui qui manquait).

Vous pouvez ensuite passer à map qui fonctionne sur votre subsequences xs (ce qui signifie que chacune de ces sous-séquences est passée à votre fonction spécialisée foldr en tant qu'argument "manquant").

Ceci est un modèle très commun et utile qui vous permet de créer des fonctions spécialisées en fixant un sous-ensemble de paramètres à une fonction plus générale.


Dans votre exemple, la "fonction spécialisée" reste anonyme. Si cela devient trop difficile à lire (ou si la fonction est utile dans de nombreux endroits), vous pouvez lui donner un nom.

-- create a new function that takes the first ten list elements 
top10 = take 10  -- call take with a "missing parameter" 

-- as opposed to 
ten = take 10 myList -- call take with all parameters to get a list 

Il peut être utile (ou confondre) à penser des fonctions Haskell comme ne prenant qu'un seul paramètre et le retour d'une fonction qui prend le paramètre suivant (qui, à son tour retourne une fonction qui prend le troisième paramètre ou un résultat clair si c'était le dernier). Une expression comme take 1 list peut alors être lue comme (take 1) list: Appelez take 1 pour obtenir une fonction, puis appelez cette fonction sur le list pour obtenir le résultat final.