2014-04-03 5 views
6

Próbowałem sprawdzić this stackoverflow answer z ghci i pojawia się następujący błąd:Błąd w ghci których nie można odtworzyć w formie pisemnej pliku Haskell

> import Data.List 
> let m = head . sort 
> m [2,3,4] 

<interactive>:5:4: 
    No instance for (Num()) arising from the literal `2' 
    Possible fix: add an instance declaration for (Num()) 
    In the expression: 2 
    In the first argument of `m', namely `[2, 3, 4]' 
    In the expression: m [2, 3, 4] 

Niestety nie mogę odtworzyć błąd w pisemnym pliku Haskell:

-- file.hs 
import Data.List 

main = do 
    let m = head . sort 
    putStrLn $ show $ m [2,3,4] 

Uruchomienie tego pliku z runhaskell file.hs daje mi oczekiwaną wartość 2. Jaki jest mój błąd w sesji ghci?

Edit: Zauważyłam, że funkcja m ma dziwny typ w ghci:

> import Data.List 
> let m = head . sort 
> :t m 
m :: [()] ->() 

Dlaczego tak się dzieje? Czy nie powinien on mieć typu Ord a => [a] -> a? Dla sort i head uzyskać oczekiwane typy:

> :t sort 
sort :: Ord a => [a] -> [a] 
> :t head 
head :: [a] -> a 
+5

Obrzydliwe ograniczenie monomorystyki uderza ponownie. Spróbuj wykonać ': set -XNoMonomorphismRestriction' przed uruchomieniem swojego kodu w ghci. – fjh

+0

@fjh: Teraz działa! Dzięki! –

Odpowiedz

7

To z winy bał ograniczeń monomorfizm. Zasadniczo, ponieważ nie określiłeś typu dla m, GHCi odgadnie to za Ciebie. W tym przypadku zakłada, że ​​m powinien mieć typ [()] ->(), mimo że wyraźnie nie jest to, co chcesz. Po prostu daj m podpis typu w GHCi, a wszystko będzie dobrze.

> :set +m -- multiline expressions, they're handy 
> let m :: Ord a => [a] -> a 
|  m = head . sort 

Możesz wyłączyć ograniczenie monomorfizm z

> :set -XNoMonomorphismRestriction 

Ale to zazwyczaj bardzo przydatne, bo inaczej trzeba podać wiele rodzajów rzeczy, które normalnie nie w trybie interaktywnym.

+0

Czy możesz wyjaśnić, dlaczego ghci odgaduje '' [()] ->() ''? –

+5

Zasadniczo, ponieważ jest to "najprostszy" typ, który spełnia ograniczenia nałożone przez Ord a => [a] -> a. – nomen

+0

@ normen: thanks! –

Powiązane problemy