Xie
Xie

Reputation: 627

Haskell: Couldn't match expected type [(Int, Int)] with actual type IO [(Int,Int)]

I am new to Haskell, when I doing the exercise, I have a function to get random pairs from[-10,10]:

randomList :: IO [Int]
randomList = randomRs (-10, 10) `fmap` newStdGen

pairs :: IO [(Int, Int)]
pairs = liftM2 zip randomList randomList

getNPairs n = take n `fmap` pairs

<Main>  getNPairs 3 
[(-6,3),(2,3),(1,-2)]

And I have also defined several new types:

data Point x y= Point Int Int  deriving (Show)
data Bool3 = True3 | False3 | Unk3 deriving (Show)
data Maybe3 a= Just3 a | Unknown3 | Missing3 deriving (Show, Eq, Ord)

How could I get a Maybe3 (Point) list which put the getNpair value to Point.
Such as if I could get pair like [(-6,3),(2,3),(1,-2)] then I get

Just3 Point -6 3, Just3 Point 2 3, Just3 Point 1 -2

How to change the type here. Now I write a function maybePoint:

getPoint (x,y) = Just3 (Point x y)
maybePoint n= map getPoint (getNPairs n)

But is shows : Couldn't match expected type [(Int, Int)] with actual type IO [(Int,Int)]

Upvotes: 0

Views: 1055

Answers (1)

ErikR
ErikR

Reputation: 52057

Sometimes it is easier to work it out in do notation.

getNPairs n has type IO [(Int,Int)], so to get at the list of pairs we need to use <-:

do ps <- getNPairs n             -- ps has type [(Int,Int)]
   ...

Now that we have a list, we can map it with getPoint:

   ...
   let points = map getPoint ps  -- points has type [Just3 Point]
   ...

But we're still in the IO monad, so we have use return to convert this pure value into a monadic one:

   ...
   return points

This do block has type IO [ Just3 Point ].

Upvotes: 1

Related Questions