я пытался
map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]
но он вернулся
["()"]
я пытался
map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]
но он вернулся
["()"]
Ваш код не делает того, что вы от него ожидаете. Задолго до того, как сработает динамическое поведение Data.Dynamic
, средство проверки типов Haskell распознает типы. Тип правой части выражения -
mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()] :: Typeable b => [b]
а тип левой части
map show :: Show a => [a] -> [String]
поэтому для их объединения переменная типа b
соотв. a
становится единым. Если бы вы скомпилировали это из обычного файла Haskell, компилятор выдаст вам предупреждение (The type variable `a' is ambigous
). Но в GHCi интерпретатор по умолчанию просто ()
.
Но это фиксирует тип fromDynamic
в выражении на Dynamic -> Maybe ()
, эффективно выбирая все элементы типа ()
.
Если вы заставляете компилятор использовать там другой тип, например указав сигнатуру типа, вы увидите, что fromDynamic
выбирает другой тип:
Prelude Data.Dynamic Data.Maybe> map (show :: Integer -> String) . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]
["3"]
К сожалению, невозможно достичь желаемого: выбрать все элементы, тип которых поддерживает экземпляр шоу, поскольку эта информация недоступна для fromDynamic
.
Проблема в том, что fromDynamic
должен перейти к мономорфному типу. Он выбирает ()
, но с сигнатурой типа вы можете заставить его выбрать любой другой тип.
Чтобы показать это, вам понадобится функция, которая по очереди пробует все возможные типы. Вероятно, вы не хотите хранить такие данные, но хотите хранить их вместе с некоторыми операциями (например, show).
Есть два способа связать. Я предпочитаю, чтобы все функции были предварительно применены к значению (так что для демонстрации вы просто получаете список преобразователей типа String
).
Другой способ - также поместить функции в Dynamic
(убедитесь, что они имеют правильный мономорфный тип!), А затем использовать dynApply
.