Dodanie typu adnotacji do ekspresji jak w
e :: type
sprawia czek kompilatora że e
ma iż type
, jak również wykorzystanie że type
prowadzenia pojazdów zmiennych typu instancji i wybór instancji. Jednak, jeśli type
jest polimorficzny, nadal można go utworzyć później. Rozważ np.
(id :: a -> a) "hello"
Powyżej a
zostanie instancja do String
, pomimo mojego adnotacji. Ponadto
foo :: Int -> Int
foo = (id :: a -> a)
uczyni a
do wystąpienia do Int
później. Powyższa adnotacja id
nie przekazuje żadnej informacji do GHC: już wie, że ten typ ma id
. Możemy usunąć to bez wpływu na sprawdzanie typu. Oznacza to, że wyrażenia id
i id :: a->a
są nie tylko dynamicznie równoważne, ale również statycznie takie.
Podobnie wyrażenia
putStrLn . show
i
(putStrLn . show) :: Show x => x -> IO()
są statycznie równoważne: jesteśmy po prostu komentowania kod z typem GHC można wywnioskować. Innymi słowy, nie dostarczamy GHC żadnych informacji, o których jeszcze nie wie.
Po sprawdzeniu adnotacji typ GHC może następnie utworzyć egzemplarz x
. Ograniczenie monomorfizmu robi to w twoim przykładzie. Aby temu zapobiec, należy użyć adnotacji dla wiążącego jesteś wprowadzające, nie dla ekspresji:
myprint :: Show x => x -> IO()
myprint = (putStrLn . show)
Dziki zgadnę: bał ograniczenie monomorfizm. – Jubobs
@Jubobs To by było również moje przypuszczenie - z wyjątkiem tego, że nie podpisu jawnego typu nie można tego wyłączyć? – MathematicalOrchid
Czy używasz starej wersji GHC? Jestem w wersji 7.8.3 i otrzymuję sygnaturę typu, której ogólnie się spodziewałeś ('Show a => a -> IO()'), nawet bez użycia wyrażenia podpisu. Uzyskanie '() -> IO()' wydaje się być rzeczywistym problemem z GHC. – MasterMastic