Haskell获取IO列表元素

时间:2015-01-01 18:36:14

标签: list haskell io element monads

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

由于文件读取,我坚持使用IO monad,具体来说,我有一个IO Deck类型的对象。如何检索卡片列表的各个元素?由于IO monad,类型似乎不再是一个列表所以我不能使用!!操作

3 个答案:

答案 0 :(得分:4)

你的主要问题是你根本不知道如何操纵monad,所以这里有一些指示:

Monads有一些功能可以让它们被操纵。这些源于monad类型类return>>=(又名'bind')中定义的基本类型。

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)

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

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

你可以找到更多操纵monad的方法,以及所涉及的各种类型签名的解释,以及do-notation和其余的here

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

假设这些是你的类型:

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 []

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