Можно ли написать инъективную функцию типа
hard :: (forall n . Maybe (f n)) -> Maybe (forall n . (f n))
как общая функциональная программа - то есть без использования error,
undefined, unsafeXXX, bottom, неисчерпаемые шаблоны или любые
функции, которые не заканчиваются?
По параметричность, для любого фиксированного f :: *->* единственного итога
жители
(forall n . Maybe (f n))
примет одну из двух форм:
Nothing
Just z
where
z :: forall n . f n
К сожалению, любая попытка case на Maybe потребует
сначала выбирая n, поэтому типы переменных шаблона внутри
ветки case больше не будут полиморфными в n. Похоже,
языка отсутствует какая-то конструкция для выполнения
case -дискриминация по полиморфному типу без создания экземпляра
тип.
Кстати, писать функцию в противоположном направлении легко:
easy :: Maybe (forall n . (f n)) -> (forall n . Maybe (f n))
easy Nothing = Nothing
easy (Just x) = Just x