String haskell问题:io字符串->;[内部]
大家好,这里的程序员很棒 我正在haskell中完成我的第一步,有一个功能让我困惑: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]]] 从错误中我发现了一些类型
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]