У меня есть функция, например, так:Многократное же тело функции для нескольких подписей типа
test :: [Block] -> [Block]
test ((Para foobar):rest) = [Para [(foobar !! 0)]] ++ rest
test ((Plain foobar):rest) = [Plain [(foobar !! 0)]] ++ rest
Block
является типом данных, который включает в себя Para
, Plain
и других. Что делает эта функция не особо важной, но я замечаю, что тело функции ([Para [(foobar !! 0)]] ++ rest
) одинаково для обоих Para
и Plain
, за исключением того, что используемым конструктором является тип foobar
.
Вопрос: Есть ли способ, чтобы кратко написать эту функцию с двумя комбинированными случаями? Нечто подобное
test :: [Block] -> [Block]
test ((ParaOrPlain foobar):rest) = [ParaOrPlain [(foobar !! 0)]] ++ rest
где первые ParaOrPlain
матчи либо Para foobar
или Plain foobar
, а второй ParaOrPlain
является Para
или Plain
соответственно.
Обратите внимание, что Block
также может быть BulletList
или OrderedList
, и я не хочу работать с ними. (Редактирование:. test x = x
для этих других типов)
Ключ в том, что я не хочу, чтобы повторить тело функции дважды, так как они идентичны (за исключением вызов Para
или Plain
).
Я получаю ощущение, что могу использовать Either
или, возможно, свой собственный тип данных, но я не уверен, как это сделать.
Редактировать Чтобы уточнить, я знаю, что моя функция тело громоздкое (я новичок в Haskell), и я благодарю различные за их отвечающие упрощения.
Однако, в центре проблемы, я хочу избежать репликации линии Para
и Plain
. Нечто подобное (в моем madeup языке ...)
# assume we have `test (x:rest)` where `x` is an arbirtrary type
if (class(x) == 'Para' or class(x) == 'Plain') {
conFun = Plain
if (class(x) == 'Para')
conFun = Para
return [conFun ...]
}
# else do nothing (ID function, test x = x)
return x:rest
т.е. я хочу знать, если это возможно в Haskell, чтобы назначить функцию конструктора в зависимости от типа входного параметра таким образом. Надеюсь, что это прояснит вопрос.
Я ответил - и удалил этот ответ - ниже, предлагая экземпляр «Functor» для «Block», который немного озарен, поскольку «Блок» даже не подходит. – jgriego
Обратите внимание, что ваш код составления более длинный и менее прозрачный, чем ваш код Haskell. Повторное использование кода - это хорошо, но ясность и последовательность лучше. – AndrewC