Haskell获取IO列表元素



我有一个由元组组成的类型同义词卡。我还有一个类型同义词 Deck 定义为 [卡](卡牌列表)。

由于读取了文件,我被 IO monad 困住了,具体来说,我有一个类型为 IO Deck 的对象。如何检索卡片列表的各个元素?由于 IO monad,该类型似乎不再是列表,所以我无法使用!!算子。

你在这里的主要问题是你根本不知道如何操作monads,所以这里有一些提示:

Monads 有一些函数可以操纵它们。这些源于 monad 类型类、return>>=(又名"绑定")中定义的基本内容。

return允许构造一个monad,>>=首先接受一个monad,然后是一个构造monad的函数,并将该函数应用于给定的值。这是您在您的情况下使用它的方式:

-- 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)

还可以使用 Control.Monad 中的函数 liftM 函数,该函数接受一个函数并将其应用于 monad,如下所示:

import Control.Monad
main = print (liftM (!! 1) ioList)

您可以在此处找到更多操作monads的方法,以及对所涉及的各种类型签名的解释,以及do表示法和其他内容。

您应该将

用于加载套牌的代码与游戏本身分开,然后将两者组合在一起。模板可以是:

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

假设这些是你的类型:

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-notation 来访问Deck

{-# LANGUAGE ScopedTypeVariables #-}
testFun :: IO Deck
testFun = do
  (x :: Deck) <- someDeck
  -- Operate here on the x value                 
  return []

<-将从IO Deck中提取Deck。请注意,此处的x类型为 Deck。您可以在 let 表达式中应用纯函数。另一种方法是使用更简单但不太直观的fmap,除非您习惯了它。

最新更新