Haskell Dynami c присвоение типа - PullRequest
0 голосов
/ 02 марта 2020

Есть ли способ «динамически» назначить (правильный) тип в Haskell. Псевдо-код того, что я имею в виду:

parseAs text theType = read text :: theType

Я уже нашел что-то под названием «Dynami c», но я не уверен, что это то, что я ищу.

1 Ответ

2 голосов
/ 02 марта 2020

Стандартный прием заключается в использовании экзистенциалов.

data Exists f where Exists :: f a -> Exists f
data Dict c a where Dict :: c a => Dict c a

С помощью этих двух инструментов вы можете написать:

parseAs :: String -> Exists (Dict Read) -> Exists Identity
parseAs s (Exists d) = Exists (go s d) where
    go :: String -> Dict Read a -> Identity a
    go s Dict = Identity (read s)

Затем вы можете построить значения типа Exists (Dict Read) на муха, чтобы стоять в качестве представления theType. Конечно, вы захотите использовать более информативное поле, чем Identity, в качестве возвращаемого типа, и это может означать, что вам нужно более информативное поле, чем Dict Read, в качестве ввода, описывающего ваш тип, но трудно сказать гораздо больше о том, как сделать это хорошо, без дальнейших подробностей о том, как вы планируете использовать эту вещь.

И позвольте мне добавить в качестве отступления: я настоятельно рекомендую не следовать этому маршруту. За исключением очень необычных обстоятельств, существуют альтернативные решения, которые проще и помогут вам получить 1014 *. С таким небольшим контекстом трудно дать очень хороший совет о том, какая альтернатива будет подходящей для вас; возможно, вопрос sh с более подробным обзором того, где вы хотите go и почему вы думаете, что это способ добраться туда, будет уместным.

...