这种事情有一个包:type-level。这有点吓人,我还没有真正探索过。但是你不应该需要那么大的力量,所以你可以滚动你自己的简单位。
如果你愿意使用UndecidableInstances
,事情就很简单了。大约像这样的东西(我不确切知道该库中的 naturals 是如何定义的;如果它不使用DataKinds
,您可能必须使用*
kind 而不是Nat
kind,并且您可能必须编写'Succ
and'Zero
而不是Succ
and Zero
- - 我在这方面不太清楚):
{-# LANGUAGE UndecidableInstances, TypeFamilies, DataKinds, TypeOperators #-}
module TAR where
-- You wouldn't actually use this line, because the library
-- provides the naturals
data Nat = Zero | Succ Nat
-- Digits and Ten to get things started
type One = Succ Zero
type Two = Succ One
type Three = Succ Two
type Four = Succ Three
type Five = Succ Four
type Six = Succ Five
type Seven = Succ Six
type Eight = Succ Seven
type Nine = Succ Eight
type Ten = Succ Nine
type family Plus (a::Nat) (b::Nat) where
Plus Zero n = n
Plus (Succ m) n = Plus m (Succ n)
type family Times (a::Nat) (b::Nat) where
Times Zero n = Zero
Times (Succ m) n = Plus n (Times m n)
type Decimal (a::[Nat]) = Decimal' a Zero
type family Decimal' (a::[Nat]) (n::Nat) where
Decimal' '[] n = n
Decimal' (a ': bs) n = Decimal' bs (Plus a (Times Ten n))
然后你可以写类似
Decimal '[One, Two, Five]
表示 125。