我试图使我的库的ghci显示类型尽可能直观,但是在使用更高级的类型功能时遇到了很多困难。
假设我在文件中有以下代码:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
import GHC.TypeLits
data Container (xs::[*]) = Container
我将其加载到ghci中,然后键入以下命令:
ghci> :t undefined :: Container '[String,String,String,String,String]
不幸的是,ghci给了我一个难看的外观:
:: Container
((':)
*
String
((':)
* String ((':) * String ((':) * String ((':) * String ('[] *))))))
ghci删除了用于类型级别字符串的糖。有什么方法可以防止ghci这样做并给我漂亮的版本吗?
在相关说明中,可以说我创建了一个类型级别的Replicate
函数
data Nat1 = Zero | Succ Nat1
type family Replicate (n::Nat1) x :: [*]
type instance Replicate Zero x = '[]
type instance Replicate (Succ n) x = x ': (Replicate n x)
type LotsOfStrings = Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String
现在,当我要求ghci使用LotsOfStrings
以下类型时:
ghci> :t undefined :: Container LotsOfStrings
ghci很好,给了我漂亮的结果:
undefined :: Container LotsOfStrings
但是如果我要求Replicate
d版本,
ghci> :t undefined :: Container (Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String)
当ghci不能代替类型同义词时,它会代替类型家族:
:: Container
((':)
*
[Char]
((':)
* [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *))))))
ghci为什么要替代类型族而不是类型同义词?有什么方法可以控制ghci何时进行替换?
[Char]
,有时将String 显示为String
?
String->String
,则其结果的类型将显示为String
。但是,如果必须从片段中构造类型,例如"abc"
(与相同'a':'b':'c':[]
),则无需保留同义词。这纯粹是猜测。
String
与类型变量f a
或统一[a]
,则[Char]
出于类似原因,它将在以后显示。