Próbuję zrozumieć RankNTypes
w Haskell i znalazłem ten przykład: (. Jeśli moje zrozumienie jest prawidłowe, jest to równoznaczne z check :: forall b c d. Eq b => (forall a. [a] -> b) -> [c] -> [d] -> Bool
)Rodzaj sprawdzeniu z RankNTypes w Haskell
check :: Eq b => (forall a. [a] -> b) -> [c] -> [d] -> Bool
check f l1 l2 = f l1 == f l2
Ok, jak na razie dobrze. Teraz, gdy wyraźne forall a
jest usuwany, GHC produkuje następujące błędy:
Could not deduce (c ~ a)
from the context (Eq b)
[…]
Could not deduce (d ~ a)
from the context (Eq b)
[…]
Wyjmując zagnieżdżona forall
, podpis typu staje
check :: forall a b c d. Eq b => ([a] -> b) -> [c] -> [d] -> Bool
Łatwo jest zrozumieć, dlaczego to się nie powiedzie wpisać sprawdzanie od l1
i l2
powinny mieć typ [a]
, abyśmy mogli przekazać je do f
, ale dlaczego nie jest tak w przypadku określania typu f
jako (forall a. [a] ->b)
? Czy fakt, że a
jest związany tylko wewnątrz parens pełną odpowiedź? To znaczy. sprawdzania typu zaakceptuje
[c] -> b ~ (forall a. [a] -> b)
[d] -> b ~ (forall a. [a] -> b)
(Edycja: Fixed. Dzięki, Boyd!)
od funkcji typu (forall a. a -> b)
może potrwać żadnej listy?
Więc to pytanie lub "dlaczego nie jest to użyteczne z tym podpisem"? – leftaroundabout