Edycja: oto naprawdę prosty przykład. Motywacja do tego przykładu poniżej.dodanie sygnatury typu wywnioskowanego ghci powoduje błąd
To kompiluje:
{-# LANGUAGE TypeFamilies #-}
type family F a b
f :: a -> F a b
f = undefined
f' [a] = f a
I ghci informuje, że:
*Main> :t f'
f' :: [a] -> F a b
Ale jeśli dodamy do tego podpisu wpisz do pliku powyżej, narzeka:
*Main> :r
[1 of 1] Compiling Main (test.hs, interpreted)
test.hs:9:14:
Couldn't match type `F a b0' with `F a b'
NB: `F' is a type function, and may not be injective
In the return type of a call of `f'
In the expression: f a
In an equation for `f'': f' [a] = f a
Failed, modules loaded: none.
Co daje ?
Motywacja:
Po obejrzeniu this question, pomyślałem, że być smart-Alec i napisać trochę rozwiązanie żart. Plan ataku powinien zaczynać się od liczb na poziomie typu (jak zwykle), a następnie napisać niewielką funkcję poziomu Args n a c
, która daje typ funkcji, który przyjmuje n
kopii a
i daje c
. Następnie możemy napisać małą klasę typów dla różnych n
i być na naszej drodze. Oto co Chcę napisać:
{-# LANGUAGE TypeFamilies #-}
data Z = Z
data S a = S a
type family Args n a c
type instance Args Z a c = c
type instance Args (S n) a c = a -> Args n a c
class OnAll n where
onAll :: n -> (b -> a) -> Args n a c -> Args n b c
instance OnAll Z where
onAll Z f c = c
instance OnAll n => OnAll (S n) where
onAll (S n) f g b = onAll n f (g (f b))
Byłem zaskoczony, aby dowiedzieć się, że to nie typ sprawdzić!
To z pewnością więcej wysiłku, niż poświęciłem na uproszczenie tego przykładu! Jakiej wersji GHC używasz, zanim spróbuję za bardzo w to zagłębić? – ehird
@ehird Sprawdziłem z ghc-7.2.2 i ghc-7.3.20111114. –
(Moje podejrzenie, FWIW, jest to, że jest to błąd w GHC, ale myślę, że '' Uwaga: 'Args 'jest funkcją typu, i może nie być wstrzykiwaczem' 'może również mieć znaczenie, błąd może po prostu być w w jaki sposób ': t' wyświetla nazwy lub tym podobne, a nie w samym sprawdzaczu liter). – ehird