принимать только четные числа? хочу проверки на этапе компиляции
> :set -XScopedTypeVariables > :set -XDataKinds > :set -XTypeFamilies > :set -XAllowAmbiguousTypes > :m + GHC.TypeLits > type IsEven n = Mod n 2 ~ 0 > foo :: forall n. (KnownNat n, IsEven n) => Integer; foo = natVal (Proxy @n) + 1 > foo @6 7 > foo @7 <interactive>:40:1: error: • Couldn't match type ‘1’ with ‘0’ arising from a use of ‘foo’ • In the expression: foo @7 In an equation for ‘it’: it = foo @7
newtype Even = Even Int toInt (Even n) = n * 2 fromInt n = if mod n 2 /= 0 then error "Can't construct Even" else Even $ n / 2 foo : Even -> ... foo n = ... $ toInt n чётность гарантируется. хотя можно даже без деления
type family Even (n :: Nat) where Even 0 = 'True Even 1 = 'False Even n = Even (n - 2) Можно такой самопал, но он ломается на больших чиселках (даже не знаю, как его исправить, не прибегая к помощи GHC.TypeLits)
Нет, конечно не гарантируется, чётность оригинального числа никто не энфоосит
точно так же, как при построении рафинированного значения
Обсуждают сегодня