0

I'm getting a type error because I'm trying to recursively add a Maybe int int the function rankP seen bellow. Because the return type of rankP is Maybe Int, and the type of rankC is a tuple of Ints, it is telling me I cannot add Int with Maybe Int.

type Prog = [Cmd]

data Cmd = LD Int
    | ADD
    | MULT
    | DUP
    | INC
    | SWAP
    | POP Int
    deriving Show       
type Stack = [Int]
type D = Stack -> Maybe Stack
type Rank = Int
type CmdRank = (Int,Int)


rankC :: Cmd -> CmdRank
rankC (LD _) = (0,1)
rankC ADD = (2,1)
rankC MULT = (2,1)
rankC DUP = (1,2)
rankC INC = (1,1)
rankC SWAP = (2,2)
rankC (POP x) = (x,0)


rankP :: Prog -> Maybe Rank
rankP [] = Nothing
rankP [x] = Just (snd(rankC x) - fst(rankC x))
rankP (x:xs) = if ((Just (snd(rankC x) - fst(rankC x)) + rankP xs) < 0) then Nothing
                    else Just (snd(rankC x) - fst(rankC x)) + (rankP xs)

Here is the error I am receiving:

hw3.hs:43:64:
    Couldn't match expected type `Int' with actual type `Maybe Rank'
    In the return type of a call of `rankP'
    In the first argument of `Just', namely `(rankP xs)'
    In the second argument of `(+)', namely `Just (rankP xs)'
Failed, modules loaded: none.
LWin
  • 13
  • 2

2 Answers2

1

I'm getting a slightly different error:

No instance for (Num (Maybe Int)) arising from a use of ‘+’
In the first argument of ‘(<)’, namely
  ‘(Just (snd (rankC x) - fst (rankC x)) + rankP xs)’
In the expression:
  ((Just (snd (rankC x) - fst (rankC x)) + rankP xs) < 0)
In the expression:
  if ((Just (snd (rankC x) - fst (rankC x)) + rankP xs) < 0) then
      Nothing
  else
      Just (snd (rankC x) - fst (rankC x)) + (rankP xs)

However, note that in

(Just (snd(rankC x) - fst(rankC x)) + rankP xs) < 0

you're trying to use + on two Maybe Rank objects, and compare the result with < to 0. Neither of these can work.

From your code, it looks like you're trying to "extract" the value of a Maybe Rank; see this question about that.

Community
  • 1
  • 1
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
0

The problem is that you are attempting to do arithmetic with a Maybe Rank when you really need to extract the Rank from the Maybe Rank before doing any math. One way to do this is directly by hand:

rankP (x:xs) = if y == Nothing
               then Nothing
               else let Just y' = y in
                    if snd(rankC x) - fst(rankC x) + y' < 0
                    then Nothing
                    else Just (snd(rankC x) - fst(rankC x) + y')
    where y = rankP xs

There are certainly more elegant ways to do this when you begin to understand the monadic properties of Maybe. I'm not there yet myself to give much help along those lines.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268