List Haskell获取IO列表元素
我有一张由元组组成的类型同义词卡片。我还有一个类型同义词Deck定义为[Card](卡片列表)List Haskell获取IO列表元素,list,haskell,io,element,monads,List,Haskell,Io,Element,Monads,我有一张由元组组成的类型同义词卡片。我还有一个类型同义词Deck定义为[Card](卡片列表) 由于文件读取,我一直使用IO monad,具体来说,我有一个IO Deck类型的对象。如何检索卡列表中的各个元素?由于IO monad,类型似乎不再是列表,因此我无法使用!!操作员。假设这些是您的类型: type Card = (Int, Int) type Deck = [Card] someDeck :: IO Deck someDeck = undefined -- Some sample
由于文件读取,我一直使用IO monad,具体来说,我有一个IO Deck类型的对象。如何检索卡列表中的各个元素?由于IO monad,类型似乎不再是列表,因此我无法使用!!操作员。假设这些是您的类型:
type Card = (Int, Int)
type Deck = [Card]
someDeck :: IO Deck
someDeck = undefined -- Some sample IO Deck which you have (from reading file etc.)
然后,您可以使用monad do表示法访问数据组
:
{-# LANGUAGE ScopedTypeVariables #-}
testFun :: IO Deck
testFun = do
(x :: Deck) <- someDeck
-- Operate here on the x value
return []
{-#语言范围的TypeVariables}
testFun::IO甲板
testFun=do
(x::Deck)您应该将用于加载游戏本身的代码从游戏中分离出来,然后在某个地方将两者结合起来。模板可以是:
import System.Environment (getArgs)
solve :: Deck -> Deck
solve deck = -- do something here
loadDeckFromFile :: FilePath -> IO Deck
loadDeckFromFile fp = -- load deck code here
main :: IO ()
main = do
deckFile <- fmap head getArgs
deck <- loadDeckFromFile deckFile
let solvedDeck = solve deck
putStrLn "Starting deck:"
print deck
putStrLn "\nSolved deck:"
print solvedDeck
导入系统环境(getArgs)
求解::Deck->Deck
解决甲板=--在这里做点什么
loadDeckFromFile::FilePath->IO组
loadDeckFromFile fp=--此处加载甲板代码
main::IO()
main=do
deckFile您的主要问题是您根本不知道如何操作monad,因此这里有一些提示:
单子有一些函数允许对它们进行操作。这些源于monad typeclass中定义的基本类型,return
和>=
(也称为“bind”)
return
允许构造单子,并且>=
首先获取单子,然后获取构造单子的函数,并将该函数应用于给定的值。这是您在案例中使用它的方式:
-- Imagine your list to be here:
ioList :: IO [Int]
ioList = return [1,2,3,4,5]
-- If we were to print the second element...
main = ioList >>= ( \a -> return (a !! 1) ) >>= print
-- We could write this in do-notation, syntactic sugar for the above:
main = do
list <- ioList
print (list !! 1)
你可以找到更多的操作monad的方法,以及对所涉及的各种类型签名的解释,还有donotation和其他方法。fmap(!!x)ioDeck
-或ioDeck>=(\deck->使用deck做一些事情)
你可以在这里找到如何操作monad:我认为这有点误导“操纵单子”。单子是一个一劳永逸的东西,一个数学概念,你不能操纵它!你也不能操纵单子值(也称为动作;我想这就是你在这里的意思).像>=
这样的运算符不操纵,而是组合这些操作。@leftaroundabout这是真的,但在初学者的水平上,用一种更基本的方式来考虑它可能是一个更好的主意,即组合操作。我当然发现用前一种方式思考更容易。你如何将其应用于过滤?我有一个过滤谓词iolist,其中io列表是IO数据组,谓词是Card->Bool。我尝试使用liftM,但不起作用。@wolx如果使用liftM(筛选器谓词),它应该可以正常工作ioList
-它对我来说就是这样。你的问题可能是你没有像我一样将函数括在括号中。你还需要导入控件。Monad
,其中liftM
来自哪里。别担心,我是通过使用fmap来管理的。:)fmap(过滤谓词)ioList编辑:你赢了,再次感谢你!
import Control.Monad
main = print (liftM (!! 1) ioList)