napisałem następujący fragment kodu:Dziwne zachowanie w GHCi
it :: Int -> Int
it n
| n < 1 = error "Invalid entry."
| n == 1 = 0
| otherwise = 1 + it (n `quot` 2)
Kiedy załadować go do GHCi, coś dziwnego się dzieje. Po raz pierwszy wywołuję funkcję it
, działa dobrze i zwraca oczekiwane wyniki. Jednak następnym razem, pojawia się następujący katastrofę:
λ: :t it
it :: Int -> Int
λ: it 2
1
λ: it 2
<interactive>:4:1:
Couldn't match expected type `a0 -> t0' with actual type `Int'
The function `it' is applied to one argument,
but its type `Int' has none
In the expression: it 2
In an equation for `it': it = it 2
λ: :t it
it :: Int
λ: it
1
Wydaje się, że typ it
jest w jakiś sposób zmodyfikowane po pierwszej rozmowy. Robi się jeszcze dziwniejsze gdy it
nazywa się wielokrotnie z main
, czyli wszystkie połączenia powrócić oczekiwanych rezultatów, ale w końcu ()
jest przypisany jako typ it
:
main :: IO()
main = do
let r1 = it 1
r2 = it 2
r3 = it 3
print r1
print r2
print r3
λ: main
0
1
1
λ: :t it
it ::()
wierzę, że jest to błąd związany z Identyfikator it
i elementy wewnętrzne GHCi, ponieważ zmiana nazwy funkcji na coś innego (jako it'
) całkowicie rozwiązuje problem. Poza tym ciało funkcji wydaje się nie mieć wpływu; Robienie let it = (+) 2
i ocenianie go wiele razy jest również problematyczne.
Każdy wgląd byłby doceniony. Wyjście ghci --version
to "wersja 7.6.3".
Dzięki za odpowiedź! Cieszę się, że to tylko kolejny przypadek dylematu "bug vs feature". :-) Z pewnością widzę użyteczność "tego", ale zastanawiam się, czy istnieje lepszy sposób, aby ta funkcja mogła zostać zaimplementowana w GHCi, aby uniknąć takiego zamieszania ... Może za pomocą specjalnego słowa kluczowego, zamiast prawidłowej funkcji Haskella identyfikator? Lub przynajmniej ostrzeżenie użytkownika podczas ładowania funkcji o nazwach zastrzeżonych GHCi ... Wreszcie, czy są jakieś inne specjalne nazwy w GHCi, o których powinienem wiedzieć? –
@alexandrelucchesi Przypominam sobie z drogi powrotnej, że Hugs używał zamiast tego '$$', chociaż można go pomylić z operatorem. Myślę, że GHCi używa zwykłego identyfikatora, ponieważ funkcja jest zaimplementowana jako normalny kod, patrz [podręcznik] (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/interactive-evaluation.html#idp7106400). Nie znam żadnych innych specjalnych nazw, ': show binding' nie wyświetla więcej. –