Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String haskell问题:io字符串->;[内部]_String_Haskell_Io_Int - Fatal编程技术网

String haskell问题:io字符串->;[内部]

String haskell问题:io字符串->;[内部],string,haskell,io,int,String,Haskell,Io,Int,大家好,这里的程序员很棒 我正在haskell中完成我的第一步,有一个功能让我困惑: import Data.List.Split getncheck_guesslist = do line <- getLine let tmp = splitOneOf ",;" line map read tmp::[Int] import Data.List.Split getncheck_guesslist=do 行[a]->[a]->[[a]]] 从错误中我发现了一些类型

大家好,这里的程序员很棒

我正在haskell中完成我的第一步,有一个功能让我困惑:

import Data.List.Split
getncheck_guesslist = do
    line <- getLine
    let tmp = splitOneOf ",;" line
    map read tmp::[Int]
import Data.List.Split
getncheck_guesslist=do
行[a]->[a]->[[a]]]

从错误中我发现了一些类型的错误,但我不知道如何解决这些冲突,因为IO对我来说仍然是个谜

我想读取由逗号或分号分隔的整数输入,并获得整数列表,以便:

  • 如何检查用户输入是否为Int类型
  • 如何将“IO字符串”类型的输入“翻译”为[Int]
提前感谢您的想法和提示
-你的ε/2

如果某个东西在
IO
monad中,你不能把它带到纯粹的外部世界进行进一步处理。而是将纯函数传递给
IO
中的函数内部


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

编写使用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])
getncheck\u guesslist=do
线
(
fmap
将是
的非中缀名称。两者都与
map
密切相关)

上面的代码对于特殊代码来说非常惯用,但是干净的代码看起来像

import Data.Maybe

maybeRead :: Read a => String -> Maybe a
maybeRead = fmap fst . listToMaybe . reads 
                               -- That fmap is using "instance Functor Maybe"

parseGuessList :: String -> [Int]
parseGuessList =  catMaybes . map maybeRead . splitOneOf ",;"

getncheck_guesslist = parseGuessList <$> getLine
(不过,请注意,我只是证明了代码是正确的,并没有真正尝试过。)

如果它变得比这更复杂,我想你应该使用一个合适的解析库。

在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
最后一点要注意的是,每当您使用名称为
somethingAndSomethingElse
的方法编写代码时,最好将
something
somethingElse
作为两个独立的方法编写和调用。对于最终版本,我只是将其重命名为
get_gustislist
,因为从概念上讲它就是这样做的。它以整数列表的形式获取猜测


作为最后一点,我已经结束了barsoap的起点
fmap

相同如果IO是一个谜,你有两个选择:要么通过学习来揭开它,要么在没有它的情况下工作,在没有IO的情况下编写函数。我建议暂时采用第二种选择。这让我感到很不舒服。我不打算投反对票,但我有一种感觉,原来的海报上也出现了这种情况。
import Data.Maybe

maybeRead :: Read a => String -> Maybe a
maybeRead = fmap fst . listToMaybe . reads 
                               -- That fmap is using "instance Functor Maybe"

parseGuessList :: String -> [Int]
parseGuessList =  catMaybes . map maybeRead . splitOneOf ",;"

getncheck_guesslist = parseGuessList <$> getLine
parseGuessList xs = if success then Just . catMaybes $ ys else Nothing 
  where ys :: String -> [Mabye Int]
        ys = map maybeRead . splitOneOf ",;" $ xs
        success = all isJust ys
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
get_guesslist = check_guesslist `fmap` getLine
-- or, taking it a step further
get_guesslist = (map read . splitOneOf ",;") `fmap` getLine :: IO [Int]