[英]Behavior of type level naturals in GHC 7.8
如果你想要按長度索引的向量,你可以這樣做:
{-# LANGUAGE
DataKinds, GADTs, TypeOperators, TypeFamilies, StandaloneDeriving
#-}
data N = P N | Z
type family Add (n :: N) (m :: N) :: N
type instance Add Z a = a
type instance Add (P a) b = P (Add a b)
infixr 5 :>
data Vect n a where
V0 :: Vect Z a
(:>) :: a -> Vect n a -> Vect (P n) a
deriving instance Show a => Show (Vect n a)
concatV :: Vect n a -> Vect m a -> Vect (Add n m) a
concatV V0 y = y
concatV (x :> xs) y = x :> concatV xs y
在ghc 7.8中我希望這對於新類型文字會過時,但是直接轉換是無效的:
{-# LANGUAGE
DataKinds, GADTs, TypeOperators, TypeFamilies, StandaloneDeriving
#-}
import GHC.TypeLits
infixr 5 :>
data Vect (n :: Nat) a where
V0 :: Vect 0 a
(:>) :: a -> Vect n a -> Vect (n+1) a
deriving instance Show a => Show (Vect n a)
concatV :: Vect n a -> Vect m a -> Vect (n + m) a
concatV V0 y = y
concatV (x :> xs) y = x :> concatV xs y
Unfortunatley這給出了一個錯誤: NB:
+'是一個類型函數,可能不是單射的。 我理解為什么會發生這種情況,但是因為類型文字仍然是編譯器魔法,所以我不知道為什么編譯器也無法將其魔法化。
我嘗試改變Vect
: (:>) :: a -> Vect (n-1) a -> Vect na
。 這種方式有一個內部向量的顯式公式,但這給出了錯誤:
Couldn't match type `(n + m) - 1' with `(n - 1) + m'
Expected type: Vect ((n + m) - 1) a
Actual type: Vect ((n - 1) + m) a
所以現在它需要基本算術的證明。 我無法使任何一個版本工作。 有沒有辦法為編譯器編寫(n + m) - o == (n - o) + m
的證明,或以某種方式使第一個版本工作?
類型級自然仍然沒有真正做計算。 GHC 7.10預計將集成SMT求解器,最終處理您認為應該能夠完成的所有事情。
作為一個理論上不合理但可以回答你實際問題的方法 - 當你知道兩個表達式具有相同的類型但編譯器沒有時, unsafeCoerce
存在了。
GHC 7.8求解器仍然不能解決與自然類型的許多算術關系。 雖然在這種情況下使用unsafeCoerce
強制GHC識別預期類型是完全安全的。
{-# LANGUAGE
DataKinds, GADTs, TypeOperators, TypeFamilies, StandaloneDeriving
#-}
import GHC.TypeLits
import Unsafe.Coerce
infixr 5 :>
data Vect (n :: Nat) a where
V0 :: Vect 0 a
(:>) :: a -> Vect n a -> Vect (n+1) a
deriving instance Show a => Show (Vect n a)
concatV :: Vect n a -> Vect m a -> Vect (n + m) a
concatV V0 y = unsafeCoerce y
concatV (x :> xs) y = unsafeCoerce $ x :> concatV xs y
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.