如何使递归函数工作?

时间:2015-05-23 17:53:10

标签: haskell

我这里有一些简单的haskell代码,滚动两个骰子并总结它们的值。我想利用这个价值来垄断董事会。我决定使用递归函数和第一步的另一个函数。问题是我声明了递归函数来获取IO Int类型参数并返回相同类型的结果。我该如何解决这个问题。 注意:我是Haskell的新手。

import System.Random

firstMove :: IO Int
firstMove = do
  start   <- randomRIO (0, 0)
  current <- sumOfTwoDices
  return (start + current)

makeAmove :: IO Int -> IO Int
makeAmove firstMove = firstMove
makeAmove pos = do
   step <- sumOfTwoDices
   return (pos + step)

rollDice :: IO Int
rollDice = randomRIO (1, 6)

sumOfTwoDices :: IO Int
sumOfTwoDices = do
    dice1 <- rollDice
    dice2 <- rollDice
    return (dice1 + dice2)

它将pos视为Int,即使我指定它接收IO Int类型。帮助赞赏

2 个答案:

答案 0 :(得分:3)

错误实际上是posIO Int,即使+要求其参数都是Int s。您可以使用pos

提升fmap上的添加内容
makeAmove :: IO Int -> IO Int
makeAmove pos = do
   step <- sumOfTwoDices
   fmap (+ step) pos

答案 1 :(得分:1)

只是让你得到一些工作我清理了一下:

import System.Random

firstMove :: IO Int
firstMove = do
  -- randomRIO (0,0) will allways be 0 so start=0
  let start = 0
  current <- sumOfTwoDices
  return (start+current)

makeAmove :: IO Int -> IO Int
makeAmove pos = do
   cur  <- pos
   step <- sumOfTwoDices
   return (cur+step)

rollDice :: IO Int
rollDice = randomRIO (1,6)

sumOfTwoDices :: IO Int
sumOfTwoDices = do
    dice1 <- rollDice
    dice2 <- rollDice
    return $ dice1+dice2

但正如我在你的上一个问题中告诉你的那样 - 你不应该在IO monad中做所有事情 - 重写它看起来像这样:

module Monoploy where

import System.Random

type Position = Int
type Steps = Int

start :: Position
start = 0

end :: Position
end = 79 -- please note: I don't know the number of tiles on monopoly so the 79 (80 positions) will obvious be wrong ;)

-- moves around the board / wraps back to start
move :: Steps -> Position -> Position
move s p = (p+s) `mod` (end+1)

randomMove :: Position -> IO Position
randomMove pos = do
  steps <- sumOfTwoDices
  return $ move steps pos

rollDice :: IO Steps
rollDice = randomRIO (1,6)

sumOfTwoDices :: IO Int
sumOfTwoDices = do
  dice1 <- rollDice
  dice2 <- rollDice
  return $ dice1+dice2

sampleMoveFromStart :: IO Position
sampleMoveFromStart = randomMove start