IO字符串和IO数据类型

use*_*521 1 haskell

我有这个:

data SomeData = SomeData Int Int

getDataFromUser :: SomeData
getDataFromUser = do
{
    read (getLine)::SomeData;
}
Run Code Online (Sandbox Code Playgroud)

这不编译:预期类型字符串实际类型IO字符串

我怎么解决它?我需要这个数据反序列化...

ehi*_*ird 9

您试图将其getLine视为String,但它是IO String一个IO动作,在执行时会产生一个字符串.您可以do通过使用来执行它并从块内获取结果值<-,但是由于getDataFromUserIO,它的类型必须是IO SomeData:

getDataFromUser :: IO SomeData
getDataFromUser = do
  line <- getLine
  return $ read line
Run Code Online (Sandbox Code Playgroud)

更广泛地说,我建议在Haskell中阅读关于IO的教程,比如学习Haskell 关于IO章节 ; 它与大多数其他语言的IO设备截然不同,它可能需要一些时间来适应事物的组合方式; 很难用这样的具体问题回答完全理解:)


Lui*_*las 7

您需要阅读有关Haskell IO如何工作的更多信息并确保您理解它.

你的例子有几点.如果要用于read反序列化SomeData,则需要Read为该类型提供实例.您可以使用默认值:

data SomeData = SomeData Int Int deriving (Read)
Run Code Online (Sandbox Code Playgroud)

第二:getLine是一个IO返回a String而不是a 的动作String; 因为read想要一个String,这就是你的错误的原因.这更接近你想要的:

getDataFromUser :: IO SomeData
getDataFromUser = do str <- getLine
                     return (read str)
Run Code Online (Sandbox Code Playgroud)

这可以简化为以下内容,但在您过分担心之前,请确保您已理解上述示例:

getDataFromUser :: IO SomeData
getDataFromUser = liftM read getLine
Run Code Online (Sandbox Code Playgroud)