Зараз я маю справу з такою функцією:
foo = (\(a:b:c:d:e:f:_) -> foobar a b c d e f) . (++ repeat def)
Іншими словами, даючи список, він використовує перші шість елементів для чогось, і якщо список менше шести елементів, він використовує def
як очікування для відсутніх. Це загальна сума, але шматочки цього не є (просто як map fromJust . filter isJust
), тому мені це не подобається. Я спробував переписати це, щоб не потрібно було використовувати будь-яку пристратність, і отримав це:
foo [] = foobar def def def def def def
foo [a] = foobar a def def def def def
foo [a,b] = foobar a b def def def def
foo [a,b,c] = foobar a b c def def def
foo [a,b,c,d] = foobar a b c d def def
foo [a,b,c,d,e] = foobar a b c d e def
foo (a:b:c:d:e:f:_) = foobar a b c d e f
Я технічно зробив те, що хочу, але зараз це гігантський безлад. Як я можу це зробити більш елегантним і менш повторюваним способом?
case xs ++ repeat def of a:b:c:d:e:f:_ -> ...
достатньо локальний, що я б не замислювався над тим, щоб просто використовувати його та пропустити всі додаткові механізми, які наявні відповіді. Як правило, більш загальні аргументи загальної сукупності (які включають інваріантів, що підтримуються у кількох функціональних викликах, наприклад) викликають у мене нервозність.
takeWithDef
він не є корисним, якщо він повертає звичайний список, оскільки нам потрібно вирівняти відповідність тому: - / Правильне рішення - це те, що Даніел написав нижче у своїй другій відповіді. uncons
отримує лише перший елемент, тож це не так корисно.
uncons :: Default a => [a] -> (a,[a])
яке значення за замовчуваннямdef
. Або дефолтtakeWithDef
. І / або синонім візерунка / схеми перегляду. Для цього потрібно написати деякий допоміжний код помічника.