2015-12-09 3 views
2

J'essaie d'écrire une fonction Haskell qui prend deux fonctions unaires (f et g) et une liste de nombres (ns) et applique alternativement ces fonctions d'entrée f et g aux éléments de la liste entrée.Fonction Haskell qui applique alternativement les fonctions unaires d'entrée

Par exemple:

func double square [2, 3, 4, 5, 6] 

retournerait

[4, 9, 8, 25, 12] 

J'utilise WinGHCi pour mon compilateur. Toute aide sur l'écriture de cette fonction serait appréciée, merci.

+4

Check out '' zipWith' et cycle'. – luqui

+0

Voir http://stackoverflow.com/questions/17383169/haskell-double-every-2nd-element-in-list/17383354#17383354 –

+1

J'essaie de ne pas utiliser les fonctions de bibliothèque, et je ne vois pas comment zipWith aiderait ... –

Répondre

6

Si vous ne souhaitez pas utiliser les fonctions de la bibliothèque, vous pouvez le faire en utilisant récursion:

func _ _ []  = [] 
func f g (x:xs) = f x : func g f xs 
+0

En tant que ligne simple: 'interMap f g xs = foldr (\ xr f g -> f x: r g f) (\ _ _ -> []) xs f g'. – user3237465

-2

Juste une solution simple ...

fun :: (a -> b) -> (a -> b) -> [a] -> [b] 
fun f g = reverse . snd . foldl step (0,[]) 
      where 
      step (c,ac) x = (c + 1, (if even c then f x else g x) : ac) 

Puisque vous ne souhaitez pas utiliser les fonctions de la bibliothèque, vous pouvez reproduire le même résultat sans utiliser foldl. L'idée est simple d'utiliser un compteur pour savoir quelle position est égale ou non.

Editer: J'ai fait un peu de confusion sur mon accumulateur. Maintenant, c'est correct.

+0

Veuillez reconsidérer votre vote. –

+1

L'objectif était d'éviter les fonctions de la bibliothèque, pour des raisons inconnues. –

1

expansion sur le commentaire de @ Luqui:

func f1 f2 l = zipWith ($) (cycle [f1, f2]) l 

Si vous ne souhaitez pas utiliser les fonctions de bibliothèque, il suffit de regarder leurs implémentations, ils sont assez simples.