Можно ли написать инъективную функцию типа
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