Чтобы создать класс типа, который принимает натуралов на уровне типа Z, (SZ), (S (SZ)) ... и т.д., вы можете просто объявить экземпляры рекурсивно как таковой:Типичные экземпляры на основе предикатов типа?
data Z
data S a
class Type a
instance Type Z
instance Type (S a)
Является ли это возможно создать экземпляр класса типа на основе предикатов уровня уровня? Например, я хочу, чтобы иметь возможность сказать:
{-# LANGUAGE MultiParamTypeClasses #-}
class Type a b
instance Type x y when (x :+: y == 8)
Где :+:
является добавление уровня типа и ==
является уровень типа равенства из Data.Type.Equality
, так что экземпляры создаются только для пар нац, которые добавляют до 8 .
Обозначения, подобные этому, доступны в Haskell? Если нет, как это сделать?
Edit: Этот пост был вдохновлен by the Haskell wiki article on smart constructors, где тип класса InBounds
был объявлен статически проверить, что тип фантом аргумент, передаваемый в смарт-конструктор был в некотором диапазоне Nat
с, умный конструктор был:
resistor :: InBounds size => size -> Resistor size
resistor _ = Resistor
Попытки сделать что-то подобное в моем примере (после использования ответа leftaroundabout в) дает мне ошибку:
construct :: (Type a b) => a -> b -> MyType a b
construct _ _ = MyType
>>> Expected a type, but a has kind Nat…
пример из вики Haskell работает, потому что Безразлично» t использовать DataKinds, можно ли передать тип вида Nat
функции уровня ценности?
Спасибо за ответ, но это не получилось именно для того, что я пытался сделать, поэтому я обновил свой вопрос, чтобы включить больше контекста. –
Этот пример в Wiki использует типы фантомов бесполезным способом: вам вообще не нужен аргумент 'resistor', просто сделайте его' резистором :: InBounds size => Resistor size', 'resistor = Resistor'. Если вам нужно обернуть значение аргумента данных в аргументе, используйте ['Tagged'] (http://hackage.haskell.org/package/tagged) (который я не большой поклонник, но иногда это в самый раз). – leftaroundabout
Изменение моего кода на 'construct :: (Тип a) => MyType a b' ,' construct = MyType' по-прежнему дает ту же ошибку. –