Haskell - получить TypeRep из конкретного экземпляра типа - PullRequest
11 голосов
/ 08 мая 2011

Я хочу написать функцию с такой сигнатурой типа:

getTypeRep :: Typeable a => t a -> TypeRep

, где TypeRep будет представлением типа для a , а не для ta .То есть компилятор должен автоматически возвращать правильное представление типов на любых сайтах вызовов [to getTypeRep ], которые будут иметь конкретные типы для a .

Для добавления некоторыхВ контексте я хочу создать тип данных «Динамический тип», с завихрением, что он запомнит тип верхнего уровня, но не его параметр.Например, я хочу превратить MyClass в Dynamic MyClass , и указанная выше функция будет использоваться для создания экземпляров Dynamic MyClass , в которых хранится представлениевведите параметр a .

Ответы [ 3 ]

9 голосов
/ 08 мая 2011

Хорошо, как насчет использования переменных типа scoped для выбора внутреннего компонента:

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Data.Dynamic
import Data.Typeable

getTypeRep :: forall t a . Typeable a => t a -> TypeRep
getTypeRep _ = typeOf (undefined :: a)

У меня работает:

*Main> getTypeRep (Just ())
()
*Main> getTypeRep (Just 7)
Integer
*Main> getTypeRep ([True])
Bool

Интересный дизайн.

8 голосов
/ 08 мая 2011

На касательной ноте к решению Дона обратите внимание, что код редко требует ScopedTypeVariables.Это только делает решение более чистым (но менее портативным).Решение без типов областей действия:

{-# LANGUAGE ExplicitForAll #-}
import Data.Typeable

helper :: t a -> a
helper _ = undefined

getTypeRep :: forall t a. Typeable a => t a -> TypeRep
getTypeRep = typeOf . helper
0 голосов
/ 30 декабря 2016

Эта функция (сейчас) существует в Data.Typeable typeRep

...