2012-04-21 12 views
8

Mam proste funkcji takich jak:Wyjście Integer do stdout w Haskell

nth :: Integer -> Integer 

I próbuję wydrukować to wynik następująco:

main = do 
    n <- getLine 
    result <- nth (read n :: Integer) 
    print result 

następujący błąd jest generowany:

Couldn't match expected type `IO t0' with actual type `Integer' 
In the return type of a call of `nth' 
In a stmt of a 'do' expression: 
    result <- nth (read n :: Integer) 

Próbowano również z putStrLn i wieloma innymi kombinacjami bez powodzenia.
Nie mogę tego rozgryźć i potrzebowałbym pomocy, ponieważ nie w pełni rozumiem, jak działają te elementy wokół tych IO.

+2

One-liner: 'main = print. nth. read = << getLine' – JJJ

Odpowiedz

12

nth jest funkcją, a nie IO działanie:

main = do 
    n <- getLine 
    let result = nth (read n :: Integer) 
    print result 
+0

Cool! Ale dlaczego tak jest? –

+0

Ponieważ nie wykonuje żadnych operacji we/wy ...? –

+1

Czy składnia i powiązania ('x <- czynność') są używane tylko dla Monad. Jeśli jesteś początkującym, prawdopodobnie jedyną monadą, której używasz, jest 'IO'. jeśli twoja funkcja nie ma postaci 'func :: a -> IO b' lub nawet' func :: IO b', nie możesz użyć binda, ale możesz użyć instrukcji let. –

4

Składnia do rozpakowuje coś w monady. Wszystko po prawej stronie strzały musi żyć w monosie IO, w przeciwnym razie typy nie sprawdzają. An IO Integer będzie w porządku w twoim programie. do jest cukier syntaktyczny dla bardziej wyraźnej funkcji, które byłyby zapisać w następujący sposób:

Przypomnijmy, że (>>=) :: m a -> (a -> m b) -> m b

main = getLine >>= (\x -> 
     nth >>= (\y -> 
     print y)) 

Ale nth nie jest wartością monadycznego, więc nie ma sensu, aby zastosować funkcję (>>=) , który wymaga czegoś z typem IO a.

+0

Dzięki, teraz mówię "Och, więc stąd przyszło to, czego się spodziewałem" m0 a0 ", które otrzymywałem ..." –

+1

Aby wyjaśnić niewiele więcej, 'm0' pochodzi od faktu, że' (>> =) :: Monad m => ma -> (a -> mb) -> mb'. Działa dla każdej monady, nie tylko 'IO', aw twoim przypadku kompilator nie miał szansy dowiedzieć się, że' m' to 'IO', więc wstawia' m0' w komunikacie o błędzie. – nponeccop