Как зависимая пара может ввести Sigma из синглетонов использовать библиотеку?
Предположим, что существует следующий индексированный список типов и функция репликации:
data Vect :: Nat -> Type -> Type where
VNil :: Vect 0 a
VCons :: a -> Vect n a -> Vect (n + 1) a
replicateVec :: forall n a. Sing n -> a -> Vect n a
(Вы можете найти пару различных реализаций replicateVec
в этот вопрос).
Я хотел бы создать функцию replicateVecSigma
, которая возвращает Vect
в зависимой паре. В идеале было бы примерно следующее:
replicateVecSigma :: Natural -> Sigma Nat (\n -> Vect n String)
Как можно использовать Sigma
для написания этой функции? А как можно записать тип функции?
На самом деле я могу реализовать replicateVecSigma
следующим образом, но это не кажется очень чистым:
data Foo a b (m :: TyFun Nat Type)
type instance Apply (Foo a b) (n :: Nat) = a n b
replicateVecSigma :: Natural -> Sigma Nat (Foo Vect String)
replicateVecSigma i =
case toSing i of
SomeSing snat -> snat :&: replicateVec snat "hello"
К сожалению, мне приходится объявлять этот тип Foo
и экземпляр Apply
только для того, чтобы использовать Sigma
. Предоставляет ли библиотека singletons
способ упростить работу с Sigma
?
Вы можете найти мой полный код здесь.
Для полноты вот определение Sigma
:
data Sigma (s :: Type) :: (s ~> Type) -> Type where
(:&:) :: forall s t fst. Sing (fst :: s) -> t @@ fst -> Sigma s t
Вот ~>
:
type a ~> b = TyFun a b -> *
data TyFun :: * -> * -> *
instance (SingKind k1, SingKind k2) => SingKind (k1 ~> k2)
type instance Demote (k1 ~> k2) = Demote k1 -> Demote k2
class SingKind k where
type family Demote k :: * = r | r -> k
fromSing :: forall (a :: k). Sing a -> Demote k
toSing :: Demote k -> SomeSing k
Вот @@
:
type a @@ b = Apply a b
type family Apply (f :: k1 ~> k2) (x :: k1) :: k2
singletons
определяет группу экземпляров для Apply
.
Как сделать TyFun
и Apply
работает?
Вот три вопроса сверху:
- Как я могу использовать
Sigma
для написания такой функции, какreplicateVecSigma :: Natural -> Sigma Nat (\n -> Vect n String)
? - Я могу написать
replicateVecSigma
, используя приведенный выше типFoo
, но это слишком много дополнительной работы. Есть ли более простой способ? - Как работают
TyFun
иApply
?
singletons
дефункционализации кодирования функций типов. Авторsingletons
написал об этом в своем блоге а> - person Benjamin Hodgson♦   schedule 14.04.2018