2015-04-24 25 views
8

Tak więc mam funkcję apply :: proxy tf -> tf Int -> tf Int, która pobiera Proxy przeznaczony do przenoszenia rodziny typów i stosuje Int do tego typu rodziny w celu określenia typu drugiego argumentu i wartości zwracanej. Otrzymuję jednak mylące odpowiedzi od GHC.Typ Rodzina polimorfizm

{-# 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 odmawia skompilować z GHC wypluwa ten błąd:

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() 

Confusingly, zakomentowanie test1 i przy użyciu let wiążącego test2 sprawia GHC szczęśliwy i wszystko kompiluje grzywny. Czy ktoś może wyjaśnić, co tu się dzieje?

Odpowiedz

12

So I have a function apply :: proxy tf -> tf Int -> tf Int which takes a Proxy intended to carry a type family

Nie możesz tego zrobić. Typ rodziny musi być zawsze w pełni zastosowany, podobnie jak synonimy typu, których są uogólnieniem. Zmienna typu nigdy nie może być utworzona dla rodziny o niedostatecznie nasyconym typie.

Jest to błąd w GHC 7.8.3 że nie odrzuca już swój program zaczynając

f :: Proxy F