2016-04-11 3 views
1

Я только что начал изучать Haskell и написал две функции: одну для списков с четными длинами и одну для списков нечетных длин. Это означает, что «четная» функция с [0..7] возвращает [0,7,2,5,4,3,6,1], а «нечетная» функция с [0..8] возвращает [0, 7,2,5,4,3,6,1,8] - это те результаты, которые мне нужны. Однако после много работы я все еще не могу их объединить, так что для обоих списков работает только одна функция. Вот функции, и я задавался вопросом, знают ли более опытные кодировщики Haskell о решении.Определение постоянной величины при начале функции Haskell

funcOdd :: [Int] -> [Int] 
funcOdd [] = [] 
funcOdd (x:xs) = take (n+1) ((x*2) : (pred n - x):funcOdd(xs)) where n = length xs 

funcEven :: [Int] -> [Int] 
funcEven [] = [] 
funcEven (x:xs) = take (n+1) ((x*2) : (n - x):funcEven(xs)) where n = length xs 
+0

Было бы полезно, если бы вы могли объяснить предполагаемое значение и/или цель этой функции. Это пахнет, может быть, это что-то математическое. Размышление о базовом значении может привести к более простому, более чистому решению, чем к коду. – dfeuer

ответ

1

Вы можете матч шаблон, чтобы отделить случаи

fullFunction theList | even (length theList) = funcEven theList 
fullFunction theList = funcOdd theList 

при вызове fullFunction, он попробует первый случай, проверяя, если длина списка даже. Если это не удастся, он отступит во втором случае.

+0

Спасибо за это, мне не приходило в голову, что сопоставление шаблонов можно использовать для функций. –

1

Возможно уборщик этот путь

func xs = zipWith const (go xs) xs 
    where go [] = [] 
      go (x:xs) = 2*x : ((length xs)-off-x) : go xs 
      off = mod (length xs) 2 

единственное различие, которое я вижу между этими двумя функциями является использование pred n против n, который заменяется при выключенном (набор), полученных от длины исходного списка.

zipWith const ... обрезает результат с длиной исходного списка для замены take (n+1).

+0

Спасибо karakfa. Я использовал 'zipWith const ...' при выводе вашей функции сейчас, но не могу понять, как это работает. Как работает 'zipWith' в отношении функции go? Выполняет ли '(go xs) xs' как список? –

+0

это zips '(go xs)' с 'xs' и выбирает первый элемент. Это ограничение длины списка на минимальную длину двух, которая в этом случае равна длине 'xs'. fyi: 'const a b = a'. Я думаю, здесь вы можете использовать 'take x', поскольку длина уже рассчитана. – karakfa

Смежные вопросы