Я могу дать вам только ответ на Haskell, поскольку я не говорю ни на одном из этих языков.Однако мне кажется, что вы в основном ищете способ автоматически преобразовать входные данные в функцию.Похоже, он не имеет ничего общего с монадами.
(concat (scala-list 1 2) [3 4]) => (scala-list 1 2 3 4)
Если я переведу это на Haskell, я бы дал ему такой тип
concat :: (IsList l1, IsList l2) => l1 elem -> l2 elem -> [elem]
, где ToList - класс типовкоторый просто преобразует этот контейнер в список
class IsListOf a where
toList :: a elem -> [elem]
Из вашего примера неясно, как вы определитесь с типом вывода, поэтому я не могу помочь с этим.
(map + [1 2] (scala-list 3 4)) => [4 6]
В Haskell эта функция называется не map, а zipWith.Если вы хотите автоматически преобразовать ввод, вы можете сделать это следующим образом.
zipWith :: (IsList l1, IsList l2) => (a -> b -> c) -> l1 a -> l2 b -> [c]
Если вы хотите автоматически преобразовать функцию, вы можете сделать это точно так же.
zipWith :: (IsList l1, IsList l2, Is2Function f) => f a b c -> l1 a -> l2 b -> [c]
Is2Functionопять-таки это класс типов, который просто преобразуется в 2-арную функцию
class Is2Function f where
toFunction :: f a b c -> a -> b -> c
Есть также кое-что, что следует иметь в виду в отношении обобщений.В предыдущем сообщении я сказал, что не знаю, как вы определитесь с выходом.Это проблема, с которой компилятор также время от времени сталкивается (по крайней мере, в haskell), когда вы делаете много обобщений.Обобщения кажутся приятными на первый взгляд, но они не всегда проясняют ситуацию и могут привести к неоднозначности.