2016-11-21 26 views
12

Расширение DataKinds способствует «значениям» (т. Е. Конструкторам) в типы. Например, True и False становятся отличными видами вида Bool.Kind Demotion (в отличие от Kind Promotion)

Что я хотел бы сделать, это наоборот, то есть типы demote в значения. Функция этой подписи будет в порядке:

demote :: Proxy (a :: t) -> t 

я могу на самом деле сделать это, например, для Bool:

class DemoteBool (a :: Bool) where 
    demoteBool :: Proxy (a :: Bool) -> Bool 

instance DemoteBool True where 
    demoteBool _ = True 

instance DemoteBool False where 
    demoteBool _ = False 

Однако, я должен был бы писать примеры для любого типа я хочу снижаем его ценность. Есть ли лучший способ сделать это, что не связано с таким количеством шаблонов?

+1

Причина, по которой вам приходится делать это вручную, является пристрастностью. Учитывая тип 'b :: Bool' типа, вы точно не знаете, что это либо «True», либо «False». Это может быть [застрявший тип] (https://typesandkinds.wordpress.com/2015/09/09/what-are-type-families/). Синглтон доказывает, что его тип не застревает. Зависимый Haskell поможет немного в этом конкретном случае, потому что «Истина» и «Истина» будут одинаковыми, но все же есть неизбежные проблемы с пристрастностью. –

+0

@BenjaminHodgson делает существующую 'TypeInType' помощь вообще здесь, или это не связано? – porges

+0

Было бы здорово, если бы строгие поля при поднятии не могли содержать застрявших типов, так же как и строгое поле, не могут содержать дно. Я просто хочу, чтобы обладать над "a ::! Bool" и использовать его в коде :) – porges

ответ

10

Это одна из применений singletons, в частности fromSing:

ghci> :m +Data.Singletons.Prelude 
ghci> :set -XDataKinds 
ghci> fromSing (sing :: Sing 'True) 
True 

Он по-прежнему включает в себя много шаблонного, но пакет имеет много он уже определен, и я считаю, что это обеспечивает шаблон Хаскель позволяйте вам создавать свои собственные более легко (и с меньшим количеством кода).