我有几个类型别名,它们都符合类似的模式:
def url = "http://192.168.0.1/svn/myproj/trunk"
def user = "username"
def password = "password"
return svnrev = "svn info --username $user --password $password --show-item last-changed-revision $url".execute().text
我想让别名没有点,所以我可以自己使用它们。而不是定义新类型,我认为如果我可以做类型级组合,它会很整洁:
type Foo f = Bar (Qoox f)
type Faa f = Bar (Qaax f)
type Moo f = Fez (Rxoo f)
type Maa f = Fez (Rxaa f)
-- ...
但我不得不定义多个type Foo = Bar `Compose1` Qoox
type Faa = Bar `Compose1` Qaax
type Moo = Fez `Compose2` Rxoo
type Maa = Fez `Compose2` Rxaa
-- ...
类型,因为基类型有不同的类型。
我喜欢的是一种多金属类型级功能
Compose
所以我可以做到
type family (.) (m :: k1 -> k) (n :: k2 -> k1) :: k2 -> k where
但我怀疑这可能超出了Haskell目前的能力,而且我不想浪费时间去实现不可能的事情。
可以使用GHC8中提供的扩展在Haskell中完成这样的组合吗?
答案 0 :(得分:5)
我认为GHC目前无法实现这些目标。
GHCi 8.0似乎接受了这一点。
> :set -XPolyKinds
> type C (m :: k1 -> k) (n :: k2 -> k1) (t :: k2) = m (n t)
> :i C
type C (m :: k1 -> k) (n :: k2 -> k1) (t :: k2) = m (n t) :: k
但请注意,一般而言,这不能部分应用,并且需要您逐步扩展您的定义。
E.g。我们无法使用type T = C [] []
但我们可以使用type T a = C [] [] a
。
如果没有eta扩展,我认为我们不能返回类型k2 -> k
,除非它是类型构造函数。我们没有类型级lambda(或部分应用程序)。