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
Title: Web Development with Clojure, Third Edition - migrations/create not working: p159
When I execute the command:
user=> (create-...
New
Hello! On page xix of the preface, it says there is a community forum "… for help if your’re stuck on one of the exercises in this book… ...
New
@noelrappin
Running the webpack dev server, I receive the following warning:
ERROR in tsconfig.json
TS18003: No inputs were found in c...
New
I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint.
As entered, the SwitchCompat changes color to hol...
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
In general, the book isn’t yet updated for Phoenix version 1.6. On page 18 of the book, the authors indicate that an auto generated of ro...
New
Is the book’s epub format available to read on Google Play Books?
New
When running the program in chapter 8, “Implementing Combat”, the printout Health before attack was never printed so I assumed something ...
New
@mfazio23
I’ve applied the changes from Chapter 5 of the book and everything builds correctly and runs. But, when I try to start a game,...
New
I just bought this book to learn about Android development, and I’m already running into a major issue in Ch. 1, p. 20: “Update activity...
New
Other popular topics
Hello Devtalk World!
Please let us know a little about who you are and where you’re from :nerd_face:
New
Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that u...
New
No chair. I have a standing desk.
This post was split into a dedicated thread from our thread about chairs :slight_smile:
New
I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
Biggest jackpot ever apparently! :upside_down_face:
I don’t (usually) gamble/play the lottery, but working on a program to predict the...
New
Author Spotlight
Jamis Buck
@jamis
This month, we have the pleasure of spotlighting author Jamis Buck, who has written Mazes for Prog...
New
Programming Ruby is the most complete book on Ruby, covering both the language itself and the standard library as well as commonly used t...
New
I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New
This is cool!
DEEPSEEK-V3 ON M4 MAC: BLAZING FAST INFERENCE ON APPLE SILICON
We just witnessed something incredible: the largest open-s...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /java
- /haskell
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /flutter
- /elm
- /vscode
- /ash
- /html
- /opensuse
- /zig
- /centos
- /deepseek
- /php
- /scala
- /react-native
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /django
- /deno
- /kubuntu
- /arch-linux
- /nodejs
- /revery
- /ubuntu
- /spring
- /manjaro
- /lua
- /diversity
- /julia
- /markdown
- /c








