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
The following is cross-posted from the original Ray Tracer Challenge forum, from a post by garfieldnate. I’m cross-posting it so that the...
New
Title: Hands-on Rust: question about get_component (page 295)
(feel free to respond. “You dug you’re own hole… good luck”)
I have somet...
New
Page 28: It implements io.ReaderAt on the store type.
Sorry if it’s a dumb question but was the io.ReaderAt supposed to be io.ReadAt?
...
New
The generated iex result below should list products instead of product for the metadata. (page 67)
iex> product = %Product{}
%Pento....
New
Title: Web Development with Clojure, Third Edition, vB17.0 (p9)
The create table guestbook syntax suggested doesn’t seem to be accepted ...
New
Hello! Thanks for the great book.
I was attempting the Trie (chap 17) exercises and for number 4 the solution provided for the autocorre...
New
When trying to generate the protobuf .go file, I receive this error:
Unknown flag: --go_opt
libprotoc 3.12.3
MacOS 11.3.1
Googling ...
New
The markup used to display the uploaded image results in a Phoenix.LiveView.HTMLTokenizer.ParseError error.
lib/pento_web/live/product_l...
New
@mfazio23
I’m following the indications of the book and arriver ad chapter 10, but the app cannot be compiled due to an error in the Bas...
New
@parrt
In the context of Chapter 4.3, the grammar Java.g4, meant to parse Java 6 compilation units, no longer passes ANTLR (currently 4....
New
Other popular topics
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
No chair. I have a standing desk.
This post was split into a dedicated thread from our thread about chairs :slight_smile:
New
Design and develop sophisticated 2D games that are as much fun to make as they are to play. From particle effects and pathfinding to soci...
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
New
This looks like a stunning keycap set :orange_heart:
A LEGENDARY KEYBOARD LIVES ON
When you bought an Apple Macintosh computer in the e...
New
New
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig.
General-purpose programming language and toolchain for maintaini...
New
Node.js v22.14.0 has been released.
Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /haskell
- /java
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /flutter
- /vscode
- /ash
- /html
- /opensuse
- /zig
- /centos
- /deepseek
- /php
- /scala
- /react-native
- /lisp
- /textmate
- /sublime-text
- /debian
- /nixos
- /agda
- /django
- /deno
- /kubuntu
- /arch-linux
- /nodejs
- /revery
- /ubuntu
- /manjaro
- /spring
- /lua
- /diversity
- /julia
- /markdown
- /slackware








