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
Some minor things in the paper edition that says “3 2020” on the title page verso, not mentioned in the book’s errata online:
p. 186 But...
New
When I try the command to create a pair of migration files I get an error.
user=> (create-migration "guestbook")
Execution error (Ill...
New
Title: Hands-On Rust (Chapter 11: prefab)
Just played a couple of amulet-less games. With a bit of debugging, I believe that your can_p...
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
#book-python-testing-with-pytest-second-edition
Hi. Thanks for writing the book. I am just learning so this might just of been an issue ...
New
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
This is as much a suggestion as a question, as a note for others.
Locally the SGP30 wasn’t available, so I ordered a SGP40. On page 53, ...
New
On page 78 the following code appears:
<%= link_to ‘Destroy’, product,
class: ‘hover:underline’,
method: :delete,
data: { confirm...
New
The markup used to display the uploaded image results in a Phoenix.LiveView.HTMLTokenizer.ParseError error.
lib/pento_web/live/product_l...
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
Learn from the award-winning programming series that inspired the Elixir language, and go on a step-by-step journey through the most impo...
New
Hello everyone! This thread is to tell you about what authors from The Pragmatic Bookshelf are writing on Medium.
New
A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New
We’ve talked about his book briefly here but it is quickly becoming obsolete - so he’s decided to create a series of 7 podcasts, the firs...
New
If you want a quick and easy way to block any website on your Mac using Little Snitch simply…
File > New Rule:
And select Deny, O...
New
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
A Brief Review of the Minisforum V3 AMD Tablet.
Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
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
Curious what kind of results others are getting, I think actually prefer the 7B model to the 32B model, not only is it faster but the qua...
New
Open-source implementation of the classic GTA engine now running directly in your browser. Experience the reVC technology demo on DOS.Zon...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /emacs
- /haskell
- /typescript
- /svelte
- /onivim
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /flutter
- /vscode
- /elm
- /ash
- /html
- /deepseek
- /opensuse
- /zig
- /centos
- /php
- /scala
- /react-native
- /lisp
- /sublime-text
- /textmate
- /nixos
- /debian
- /agda
- /deno
- /django
- /kubuntu
- /arch-linux
- /nodejs
- /ubuntu
- /spring
- /revery
- /manjaro
- /julia
- /diversity
- /lua
- /markdown
- /laravel









