类型家族多态性

时间:2015-04-24 19:53:47

标签: haskell polymorphism type-families

所以我有一个函数apply :: proxy tf -> tf Int -> tf Int,它接受​​一个旨在携带一个类型族的代理,并将Int应用于该类型族以确定第二个参数的类型和返回值。 但是,我收到GHC的一些令人困惑的回应。

{-# LANGUAGE TypeFamilies #-}

import Data.Proxy

type family F (a :: *) :: * where
    F Int = ()

f :: Proxy F
f = Proxy

apply :: proxy tf -> tf Int -> tf Int
apply _ x = x

-- Doesn't typecheck.
test1 :: ()
test1 = apply f ()

-- Typechecks fine
test2 :: ()
test2 = let g = apply f in g ()

test1拒绝编译GHC吐出这个错误:

tftest.hs:16:9:
    Couldn't match expected type ‘()’ with actual type ‘F Int’
    In the expression: apply f ()
    In an equation for ‘test1’: test1 = apply f ()

tftest.hs:16:17:
    Couldn't match expected type ‘F Int’ with actual type ‘()’
    In the second argument of ‘apply’, namely ‘()’
    In the expression: apply f ()

令人困惑的是,评论test1并在test2中使用let绑定会让GHC感到高兴,一切都很好。谁能解释一下这里发生了什么?

1 个答案:

答案 0 :(得分:12)

  

所以我有一个函数apply :: proxy tf -> tf Int -> tf Int,它接受​​一个旨在携带类型系列的代理

你不能这样做。必须始终完全应用类型族,就像它们是泛化的类型同义词一样。类型变量永远不能实例化为欠饱和类型族。

这是GHC 7.8.3中的一个错误,它从

开始就没有拒绝你的程序
f :: Proxy F