#haskell #syntax
#haskell #синтаксис
Вопрос:
Что не так в моем коде:
insertValue file x =
if x == "10" then "ok"
else do putStrLn "Error"; file
Ответ №1:
В if..then..else
выражении обе ветви должны иметь один и тот же тип.
Одна ветвь:
"10" :: String
Другая ветвь:
do putStrLn "Error"; file :: IO ??
Поскольку я не уверен, что вы пытаетесь сделать (и компилятор тоже не уверен), я не знаю, как исправить код.
Комментарии:
1. Например, значение insertValue «99» «10» должно возвращать «ok». Значение insertValue «99» «5» должно вывести «Ошибка» и вернуть «99».
2. @newuser: В Haskell вы не можете просто выполнить некоторый ввод-вывод (или что-либо еще в монаде), а затем продолжить, как будто вы просто выполнили несколько чистых вычислений. Как только функция коснется
IO
, она «испорчена» и также должна возвращатьIO
значение.3. @newuser: Да, вы можете. Используйте
return
для преобразования чистого значения в значение, испорченное IO. например,return "ok"
иreturn file
.
Ответ №2:
Вам нужно использовать return :: a -> IO a
, чтобы «поднять» ваши строки в IO String
:
insertValue file x =
if x == "10"
then return "ok"
else do putStrLn "Error"
return file
Но вы уверены, что не хотите вызвать putStrLn "ok"
(вместо return "ok"
) и вернуть значение Maybe? В противном случае вы возвращаете file
or "ok"
, и ваш вызывающий абонент никогда не сможет определить, произошла ли ошибка при вызове insertValue
файла с именем «ok».
Ответ №3:
«ok» имеет тип «String», в то время как предложение «else» имеет тип «IO ()». В Haskell «if» — это выражение, поэтому они должны совпадать.
Трудно помочь больше, не зная, что вы пытаетесь сделать.