 
  		        molleweide
Effective Haskell: Calculator throws errors in parse'
Allright, so I have put all of the example code for Calculator in chapter 4 on page ~140 in a file and when loading it into GHCI it throws this:
    λ: :reload
    [1 of 1] Compiling Calculator       ( Calculator.hs, interpreted )
    Calculator.hs:40:9: error:
        • Couldn't match expected type ‘String -> Either String a1’
                      with actual type ‘Either String b0’
        • In the pattern: Left err
          In a case alternative: Left err -> Left err
          In the expression:
            case readEither of
              Left err -> Left err
              Right lit' -> Right (Lit lit', rest)
       |
    40 |         Left err -> Left err
       |         ^^^^^^^^
    Calculator.hs:41:9: error:
        • Couldn't match expected type ‘String -> Either String a1’
                      with actual type ‘Either a0 Int’
        • In the pattern: Right lit'
          In a case alternative: Right lit' -> Right (Lit lit', rest)
          In the expression:
            case readEither of
              Left err -> Left err
              Right lit' -> Right (Lit lit', rest)
       |
    41 |         Right lit' -> Right (Lit lit', rest)
       |         ^^^^^^^^^^
    Failed, no modules loaded.
I am not sure if maybe there is something that you forgot to add or that should be added.
Below I post my full calculator module:
module Calculator where
import Text.Read (readEither)
data Expr = Lit Int
  | Add Expr Expr
  | Sub Expr Expr
  | Mul Expr Expr
  | Div Expr Expr
eval :: Expr -> Int
eval expr =
  case expr of
    Lit num -> num
    Add arg1 arg2 -> eval' ( + ) arg1 arg2
    Sub arg1 arg2 -> eval' ( - ) arg1 arg2
    Mul arg1 arg2 -> eval' ( * ) arg1 arg2
    Div arg1 arg2 -> eval' div arg1 arg2
    where
      eval' :: (Int -> Int -> Int) -> Expr -> Expr -> Int
      eval' operator arg1 arg2 = operator (eval arg1) (eval arg2)
parse :: String -> Either String Expr
parse str =
  case parse' (words str) of
    Left err          -> Left err
    Right (e, [])     -> Right e
    Right (_, rest)   -> Left $ "Found extra tokens: " <> (unwords rest)
parse' :: [String] -> Either String (Expr, [String])
parse' [] = Left "unexpected end of expression"
parse' (token:rest) =
  case token of
    "+" -> parseBinary Add rest
    "*" -> parseBinary Mul rest
    "-" -> parseBinary Sub rest
    "/" -> parseBinary Div rest
    lit ->
      case readEither of
        Left err -> Left err
        Right lit' -> Right (Lit lit', rest)
parseBinary :: (Expr -> Expr -> Expr) -> [String] -> Either String (Expr, [String])
parseBinary exprConstructor args =
  case parse' args of
    Left err -> Left err
    Right (firstArg, rest') ->
      case parse' rest' of
        Left err -> Left err
        Right (secondArg, rest'') ->
          Right $ (exprConstructor firstArg secondArg, rest'')
run :: String -> String
run expr =
  case parse expr of
    Left err -> "Error: " <> err
    Right expr' ->
      let answer = show $ eval expr'
      in "The answer is: " <> answer
First Post!
 
		        RebeccaSkinner
									Author of Effective Haskell
			          
						Hi, it looks like you’re missing the lit parameter to readEither in the parse' function. The correct version of the function is:
parse' :: [String] -> Either String (Expr, [String])
parse' [] = Left "unexpected end of expression"
parse' (token:rest) =
  case token of
    "+" -> parseBinary Add rest
    "*" -> parseBinary Mul rest
    "-" -> parseBinary Sub rest
    "/" -> parseBinary Div rest
    lit ->
      case readEither lit of
        Left err -> Left err
        Right lit' -> Right (Lit lit', rest)
It looks like this is fixed in the most recent version- thanks for the catch and sorry for the trouble!
Popular Pragmatic Bookshelf topics
                         
                      
                       
          
                In Chapter 3, the source for index introduces Config on page 31, followed by more code including tests; Config isn’t introduced until pag...
              
            
            
          
              New
 
          
                page 37 
ANTLRInputStream input = new ANTLRInputStream(is); 
as of ANTLR 4 .8 should be: 
CharStream stream = CharStreams.fromStream(i...
              
            
            
          
              New
 
          
                Hello Brian, 
I have  some problems with running the code in your book. I like the style of the book very much and I have learnt a lot as...
              
            
            
          
              New
 
          
                Title: Hands-On Rust (Chap 8 (Adding a Heads Up Display) 
It looks like 
    .with_simple_console_no_bg(SCREEN_WIDTH*2, SCREEN_HEIGHT*2...
              
            
            
          
              New
 
          
                I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint. 
As entered, the SwitchCompat changes color to hol...
              
            
            
          
              New
 
          
                Hi, I have just acquired Michael Fazio’s “Kotlin and Android Development” to learn about game programming for Android. I have a game in p...
              
            
            
          
              New
 
          
                I’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
              
            
            
          
              New
 
          
                The allprojects block listed on page 245 produces the following error when syncing gradle: 
“org.gradle.api.GradleScriptException: A prob...
              
            
            
          
              New
 
          
                Skimming ahead, much of the following is explained in Chapter 3, but new readers (like me!) will hit a roadblock in Chapter 2 with their ...
              
            
            
          
              New
 
          
                I am using Android Studio Chipmunk | 2021.2.1 Patch 2 
Build #AI-212.5712.43.2112.8815526, built on July 10, 2022 
Runtime version: 11.0....
              
            
            
          
              New
Other popular topics
                         
                      
                       
          
                Reading something? Working on something? Planning something? Changing jobs even!? 
If you’re up for sharing, please let us know what you’...
              
            
            
          
              New
 
          
                Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
              
            
            
          
              New
 
          New
 
          
                poll
poll
Be sure to check out @Dusty’s article posted here: An Introduction to Alternative Keyboard Layouts It’s one of the best write-...
              
            
            
              
          
              New
New
 
          
                Continuing the discussion from Thinking about learning Crystal, let’s discuss - I was wondering which languages don’t GC - maybe we can c...
              
            
            
          
              New
 
          
                Was just curious to see if any were around, found this one: 
I got 51/100: 
  
Not sure if it was meant to buy I am sure at times the b...
              
            
            
          
              New
 
          
                Author Spotlight 
Mike Riley 
@mriley 
This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
              
            
            
          
              New
 
          
                I’m able to do the “artistic” part of game-development; character designing/modeling, music, environment modeling, etc. 
However, I don’t...
              
            
            
          
              New
 
          
                Ok, well here are some thoughts and opinions on some of the ergonomic keyboards I have, I guess like mini review of each that I use enoug...
              
            
            
          
              New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /ruby
- /wasm
- /erlang
- /phoenix
- /keyboards
- /python
- /rails
- /js
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /haskell
- /java
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /flutter
- /vscode
- /ash
- /opensuse
- /html
- /centos
- /php
- /deepseek
- /zig
- /scala
- /sublime-text
- /lisp
- /textmate
- /react-native
- /nixos
- /debian
- /agda
- /kubuntu
- /arch-linux
- /django
- /revery
- /deno
- /ubuntu
- /nodejs
- /manjaro
- /spring
- /diversity
- /lua
- /julia
- /slackware
- /c
 
    





