Haskell: показать все элементы, отображаемые в Hlist

я пытался

map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn ()]

но он вернулся

["()"]

person rbarreiro    schedule 04.02.2013    source источник
comment
Вам действительно нужно хранить смешанные данные в таком списке?   -  person AndrewC    schedule 05.02.2013
comment
Например, вы можете использовать запись для более простого хранения этих данных, и вы легко сможете использовать такие функции, как show, для элементов, потому что типы доступны во время выполнения. Фиксирование типов во время выполнения является преимуществом, а не недостатком, поэтому вы должны делать это, когда это возможно.   -  person AndrewC    schedule 05.02.2013
comment
Эта проблема была придумана, чтобы проиллюстрировать мою проблему. Проект, над которым я работаю, находится здесь github.com/rbarreiro/farofias. Следующим шагом в проекте является добавление функций, которые не являются экземпляром Data.Data.   -  person rbarreiro    schedule 05.02.2013


Ответы (2)


Ваш код не делает того, что вы от него ожидаете. Задолго до того, как сработает динамическое поведение 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.

person Joachim Breitner    schedule 04.02.2013

Проблема в том, что fromDynamic должен перейти к мономорфному типу. Он выбирает (), но с сигнатурой типа вы можете заставить его выбрать любой другой тип.

Чтобы показать это, вам понадобится функция, которая по очереди пробует все возможные типы. Вероятно, вы не хотите хранить такие данные, но хотите хранить их вместе с некоторыми операциями (например, show).

Есть два способа связать. Я предпочитаю, чтобы все функции были предварительно применены к значению (так что для демонстрации вы просто получаете список преобразователей типа String).

Другой способ - также поместить функции в Dynamic (убедитесь, что они имеют правильный мономорфный тип!), А затем использовать dynApply.

person singpolyma    schedule 04.02.2013
comment
хорошая идея: хранить его вместе с некоторыми операциями - person rbarreiro; 05.02.2013