Haskell IO Function -> Ошибка соответствия типа - PullRequest
3 голосов
/ 25 января 2012

Я разрабатываю функцию, которая читает пользовательский ввод в форме "a 2", а затем преобразует его в кортеж и добавляет его в список кортежей.Это должно происходить до тех пор, пока пользователь не введет «done».

Код выглядит следующим образом ...

getVectorData vector1 =  do
                putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: "
                appData <- getLine

                if appData == "done" then
                    putStrLn "That's it"
                else do
                    createVectorTuple (words appData) : vector1
                    getVectorData vector1

createVectorTuple :: [String] -> (String, Float)
createVectorTuple vectorData = ((head vectorData) , (read (last vectorData) :: Float))

Как бы то ни было, при попытке выполнить этот файл я получаюошибка

> ERROR file:.\MainApp.hs:13 - Type error in final generator
*** Term           : getVectorData vector1
*** Type           : IO ()
*** Does not match : [a]

Что я делаю не так?

Ответы [ 4 ]

4 голосов
/ 25 января 2012

Вы смешиваете IO с чисто не IO функциями.

getVectorData vector1 =  do
    putStrLn "Enter dimension and coefficient separated by a space: Enter \"Done\" to move on to next vector: "
    appData <- getLine

    if appData == "done" then
        putStrLn "That's it"

Все вышеперечисленное IO

    else do
        createVectorTuple (words appData) : vector1

createVectorTuple - это не- IO функция. Поскольку предыдущая часть является блоком do IO, в этом блоке do могут появляться только выражения типа IO a. Тем не менее, вы получаете несколько странное сообщение об ошибке, потому что приоритет приложения функции является наивысшим, поэтому строка выше анализируется

(createVectorTuple (words appData)) : vector1

, который является выражением типа [(String, Float)] (если vector1 имеет этот тип). Теперь [] также является монадой, поэтому выражения типа [a] могут появляться в do-блоках, но тогда все выражения в этом блоке должны иметь тип списка. Но

        getVectorData vector1

является выражением типа IO (), как было определено в приведенной выше части. Таким образом, типы не совпадают. По общему признанию, сообщенная ошибка типа не является самой ясной возможной в этой ситуации.

Вы, вероятно, хотите что-то вроде

let vector2 = createVectorTuple (words appData) : vector1
getVectorData vector2

или что-то совсем другое, я не могу сказать по короткому фрагменту.

2 голосов
/ 25 января 2012

Трудно сказать, но «createVectorTuple не относится к типу« IO () », так что это, вероятно, реальная проблема. Предложения« do »могут иметь много разных типов, поэтому вывод типа, вероятно, делает неправильныйпредположение основано на "createVectorTuple", а затем появляется сообщение об ошибке, потому что следующая строка не соответствует его предположению.

То, что вы, вероятно, хотите сказать, это

else
   getVectorData $ createVectorTuple (words appData) : vector1
0 голосов
/ 26 января 2012

Вам также нужно будет return что-то после putStrLn "Вот и все". поэтому обе ветви if имеют одинаковый тип. Что-то вроде:

if appData == "done" then do
       putStrLn "That's it"
       return vector1
    else getVectorData (createVectorTuple (words appData) : vector1)
0 голосов
/ 25 января 2012

Вы хотели:

else do
    let vector1 = createVectorTuple (words appData)
    getVectorData vector1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...