haskell-problem:io string - > [int]

eps*_*lbe 8 string io int haskell

你好伟大的程序员在那里,

我正在使用haskell的第一步,并且有一个令我困惑的功能:

import Data.List.Split
getncheck_guesslist = do
    line <- getLine
    let tmp = splitOneOf ",;" line
    map read tmp::[Int]
Run Code Online (Sandbox Code Playgroud)

splitOneOf在Data.List.Split中(我用cabal安装拆分安装它) splitOneOf :: (Eq a)=> [a]->[a]->[[a]]

从错误我得到它有一些类型不正确 - 但不知道如何解决这个冲突,因为IO对我来说仍然是一个谜

我想读取用逗号或分号分隔的整数输入,并得到一个整数列表,这样:

  • 如何检查用户输入是否为Int类型
  • 如何将"IO String"类型的输入"转换"为[Int]

提前感谢您的想法和提示 - 您的ε/ 2

por*_*ges 12

当您编写使用IO monad的函数时,要从函数返回的任何值也必须位于IO monad中.

这意味着[Int],您必须返回带有类型的内容,而不是返回带有类型的值IO [Int].要做到这一点,你可以使用return"包装"值的函数IO(它实际上适用于任何 monad).

只需更改最后一行以包装您的值return,如下所示:

getncheck_guesslist = do
    line <- getLine
    let tmp = splitOneOf ",;" line
    return (map read tmp :: [Int])
Run Code Online (Sandbox Code Playgroud)


Dan*_*ton 7

在Haskell中执行此操作的"正确方法"是将IO与其他所有内容分开.您的代码的直接翻译将是这样的:

getncheck_guesslist :: IO [Int]
getncheck_guesslist = do line <- getLine               -- get
                         return (check_guesslist line) -- check

check_guesslist :: String -> [Int]
check_guesslist line = let tmp = splitOneOf ",;" line
                       in map read tmp
Run Code Online (Sandbox Code Playgroud)

请注意,这getncheck_guesslist只是一个IO动作.该函数没有输入参数,即使它确实需要(IO)输入getLine.

另请注意,这getncheck_guesslist是对getLineIO操作的简单修改.是不是有一个组合器可以让我推动一个函数来对monad中的值进行操作?停止.霍格时间!

我有一个功能(a -> b).我有一个输入类型的值,但它被卡在monad中m a.我想在monad中执行函数,所以结果也不可避免地会卡在monad中m b.把它们放在一起,我们hoogle (a -> b) -> m a -> m b.瞧,这fmap正是我们所寻求的.

get_guesslist = check_guesslist `fmap` getLine
-- or, taking it a step further
get_guesslist = (map read . splitOneOf ",;") `fmap` getLine :: IO [Int]
Run Code Online (Sandbox Code Playgroud)

最后要注意的是,无论何时使用类似名称somethingAndSomethingElse编写方法,编写和调用的编码风格通常都会更好,something并且somethingElse作为两个单独的方法.对于最终版本,我只是将其重命名get_guesslist,因为从概念上讲它就是它的作用.它得到了作为Ints列表的猜测.

作为最后的最后一点,我已经离开了baroap开始的地步.;)fmap是一样的<$>.


900*_*000 2

如果某个东西在IO单子之内,你就不能把它带到纯粹的外部世界进行进一步处理。相反,您可以传递纯函数以在IO.

最后,您的程序读取一些输入并写入一些输出,因此您的 main 函数将与 一起使用IO,否则您将无法输出任何内容。不要读取IO String和创建一个[Int],而是将消耗它的函数传递[Int]到您的 main 函数中并在内部使用它do