2015-02-17 2 views
0

У меня проблема с сценарием Haskell. Я пытаюсь научиться Haskell, делая проблемы, которые я нахожу в Интернете. Вход я получаю: Int -> Количество тестовых S1 -> Строка 1 для каждого теста S2 -> Строка 2 для каждого тестаПроблема с Haskell (не соответствует типу «IO Integer» с «Int»)

Каждый S1 и S2 представляет собой пространство с разделителями строка чисел. Я конвертирую их в список Ints с функцией strToIntList. Затем я хочу обработать два списка и вернуть целочисленное значение на основе результатов. Я получаю следующую ошибку: Couldn't match type 'IO Integer' with 'Int' в строке 24, и я смотрел целую вечность, но просто не могу понять, почему (полная ошибка в конце сообщения).

Если кто-то может объяснить, почему я ошибаюсь, я был бы очень благодарен.

Это мой сценарий:

import Data.List 
import Data.List.Split 

main = do 
    cases <- readLn 
    doLoop cases 

toInt x = read x :: Int 

strToIntList s = [read x :: Int | x <- (splitOn " " s)] 

minOfTwo :: Int 
minOfTwo = do 
    sa <- getLine 
    sb <- getLine 
    return $ minimum [1..50] 
    -- return $ minimum $ strToIntList sa 

doLoop 0 = return() 
doLoop loopIndex = do 
    q <- getLine 
    let c = minOfTwo 
    print(c) 
    doLoop (loopIndex-1) 

Это полная ошибка я получаю:

Couldn't match type `IO Integer' with `Int' 
Expected type: IO String -> (String -> IO Integer) -> Int 
    Actual type: IO String -> (String -> IO Integer) -> IO Integer 
In a stmt of a 'do' block: sa <- getLine 
In the expression: 
    do { sa <- getLine; 
     sb <- getLine; 
     return $ minimum [1 .. 50] } 
In an equation for `minOfTwo': 
    minOfTwo 
     = do { sa <- getLine; 
      sb <- getLine; 
      return $ minimum [1 .. 50] } 
+2

Ваша функция 'minOfTwo' должна иметь тип' IO', если она 'IO', измените ее на' minOfTwo :: IO Int'. – bheklilr

+2

В качестве побочного примечания вам лучше использовать 'readMaybe' из' Text.Read' вместо 'read', так как он вернет' Nothing', если не будет синтаксический анализ вместо сбоя вашей программы. Это означает, что вам придется написать немного больше кода для его обработки, но писать немного больше кода для правильной обработки ошибок обычно считается хорошей вещью. Для быстрых одноразовых скриптов хорошо использовать небезопасные функции, такие как 'read'. – bheklilr

+0

Спасибо, беклильр. Потому что это для обучения, и вход гарантированно будет правильным, я не слишком беспокоюсь о проверке ввода еще. – buck

ответ

2

getLine функция в IO монады, и поэтому любая функция, которая вызывает getLine сусло также быть в монаде IO. Измените подпись своего типа на minOfTwo от Int до IO Int, и эта конкретная проблема исчезнет.

(Вам также нужно изменить let c = minOfTwo в c <- minOfTwo.)

Там могут быть и другие ошибки, но это один вызывает ваше сообщение об ошибке.

+0

Спасибо! Это потому, что, когда функция использует IO, результаты не гарантируются одинаковыми при каждом вызове с теми же аргументами? – buck

Смежные вопросы