2012-04-21 20 views
8

Tôi có một chức năng đơn giản như:Output Integer stdout trong Haskell

nth :: Integer -> Integer 

Và tôi cố gắng để in nó cho kết quả như sau:

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

Các lỗi sau đây được tạo:

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) 

Cũng đã thử với putStrLn và nhiều kết hợp khác không có may mắn.
Tôi không thể hình dung ra và tôi cần một số trợ giúp, vì tôi không hiểu rõ cách thức hoạt động của các công cụ này xung quanh các số IO này.

+2

một lớp lót: 'main = print. nth. read = << getLine' – JJJ

Trả lời

12

nth là một chức năng, không phải là một hành động IO:

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

Tuyệt vời! Nhưng, tại sao vậy? –

+0

Bởi vì nó không làm bất kỳ I/O ...? –

+1

Cú pháp và liên kết ('x <- action') chỉ được sử dụng cho Monads. Nếu bạn là người mới bắt đầu thì cơ hội là đơn nguyên duy nhất bạn đang sử dụng là 'IO'. nếu hàm của bạn không ở dạng 'func :: a -> IO b' hoặc thậm chí chỉ' func :: IO b', thì bạn không thể sử dụng bind nhưng bạn có thể sử dụng câu lệnh let. –

4

Cú pháp do unwraps gì đó trong một đơn nguyên. Tất cả mọi thứ ở phía bên tay phải của mũi tên phải nằm trong đơn nguyên IO, nếu không các loại không kiểm tra. An IO Integer sẽ ổn trong chương trình của bạn. do là cú pháp đường cho các chức năng rõ ràng hơn mà sẽ được viết như sau:

Nhớ lại rằng (>>=) :: m a -> (a -> m b) -> m b

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

Nhưng nth không phải là một giá trị monadic, vì vậy nó không có ý nghĩa để áp dụng các chức năng (>>=) , yêu cầu thứ gì đó có loại IO a.

+0

Cảm ơn, bây giờ tôi giống như "Ồ, do đó, từ đây đến dự kiến' m0 a0' Tôi đã nhận được ... " –

+1

Để làm rõ hơn,' m0' xuất phát từ thực tế là '(>> =) :: Monad m => ma -> (a -> mb) -> mb'. Nó hoạt động cho bất kỳ đơn nguyên nào, không chỉ 'IO', và trong trình biên dịch trường hợp của bạn không có cơ hội để tìm ra rằng' m' là 'IO', vì vậy nó đặt' m0' trong thông báo lỗi. – nponeccop