2017-10-21 3 views
1

Ich versuche, Rekursion und Funktionen höherer Ordnung zu verwenden, um etwas mit dem ersten Element einer Liste und dann mit jedem anderen Element in der Liste zu tun, z , 3., 5. .. usw.Nicht erschöpfende Musterfehler in der rekursiven Funktion

Das Problem, das ich habe, ist, dass es mir den non-exhaustive pattern Fehler gibt. Jede Hilfe wäre willkommen. Hier ist, was ich bisher:

applyToEveryOther :: (a -> b) -> [a] -> [b] 
applyToEveryOther _ [] = [] 
applyToEveryOther f (x:y:xs) = f x : applyToEveryOther f xs 

und diese sind einige zusätzliche Zeilen, die ich versucht habe, aber nicht helfen:

applyToEveryOther _ [x] = f x 
applyToEveryOther f [x] = f x 
+1

Mögliches Duplikat von [Haskell: Doppelt jedes zweite Element in der Liste] (https://stackoverflow.com/questions/17383169/haskell-double-every-2nd-element-in-list) – cdk

Antwort

4

Das einzige Element Fall sollte auch eine Liste zurück (vom Typ [b]):

applyToEveryOther f [x] = [f x] 
+0

Danke, das hat funktioniert! –

+0

Wenn ich noch eine Frage dazu habe ... Wenn ich die ganze Liste wirklich behalten wollte, nicht nur die, die transformiert wurden, wie würde ich das tun? Ich bin neu in diesem und war mir nicht sicher, ob ich einen neuen Beitrag mache oder nicht –

+0

@loutej definitiv einen neuen Beitrag! (Ich denke, die Antwort ist "f x: y: applyToEveryOther f xs", aber es wird besser formatiert und nützlicher für andere als ein neuer Beitrag). –

1

andere Lösung, die keine explizite Rekursion verwendet, sondern nur Funktionen höherer Ordnung:

import Data.List (cycle) 

applyToEveryOther f = zipWith ($) (cycle [f, id]) 

cycle schafft eine unendliche Liste von f Funktionen abwechselnd, id, f, id usw.

zipWith ($) wendet die Funktionen in der Liste auf die entsprechenden Elemente Ihrer Eingabeliste.

[(+1), id, (+1), id, (+1), id, (+1), id, ...] 
[ 1, 2, 3, 4, 5, 6, 7, 8  ] 
============================================= 
[ 2, 2, 4, 4, 6, 6, 8, 8  ] 

(Hutspitze: das Problem des eine Liste von Funktionen abschnittsweise auf eine Liste von Argumenten Anwendung zusammen mit einer Lösung zipWith ($), appeared recently auf dem Twitter-Feed 1HaskellADay verwenden.)

(Meine eigene minderwertige Lösung wurde die ZipList Typkonstruktor gefunden zu verwenden, in Control.Applicative, hier angewendet wird, würde es so etwas wie

import Control.Applicative 

applyToEveryOther f xs = let fs = cycle [f,id] 
          in getZipList (ZipList fs <*> ZipList xs) 

)

aussehen
Verwandte Themen