billboswell

billboswell

Effective Haskell: Chapter 10 (pages 379-383) - code does not compile

Under “Building a Basic Metrics System with IORefs”, have created a sample file with the code snippets from page 379-383 as follows:


module Metrics where

import qualified Data.Map.Strict as Map
import Data.IORef
import Data.Maybe (fromMaybe)
import Data.Time.Clock
( diffUTCTime
, getCurrentTime
, nominalDiffTimeToSeconds
)

data AppMetrics = AppMetrics
{ successCount :: Int
, failureCount :: Int
, callDuration :: Map.Map String Int
} deriving Show

metrics :: IO (IORef AppMetrics)
metrics = newIORef AppMetrics
{ successCount = 0
, failureCount = 0
, callDuration = Map.empty
}

printMetrics :: IO ()
printMetrics = metrics >>= readIORef >>= print

incrementSuccess :: IO ()
incrementSuccess =
metrics >>= flip modifyIORef incrementSuccess
where
incrementSuccess m =
m { successCount = 1 + successCount m}

successfullyPrintHello :: IO ()
successfullyPrintHello = do
print “Hello”
incrementSuccess

printHelloAndMetrics = do
successfullyPrintHello
printMetrics

newtype Metrics = Metrics { appMetricsStore :: IORef AppMetrics}

newMetrics :: IO Metrics
newMetrics =
let
emptyAppMetrics = AppMetrics
{ successCount = 0
, failureCount = 0
, callDuration = Map.empty
}
in Metrics <$> newIORef emptyAppMetrics

tickSuccess :: Metrics → IO ()
tickSuccess (Metrics metricsRef) = modifyIORef metricsRef $ \m →
m { successCount = 1 + successCount m}

tickFailure :: Metrics → IO ()
tickFailure (Metrics metricsRef) = modifyIORef metricsRef $ \m →
m { failureCount = 1 + failureCount m}

timeFunction :: Metrics → String → IO a → IO a
timeFunction (Metrics metrics) actionName action = do
startTime ← getCurrentTime
result ← action
endTime ← getCurrentTime

modifyIORef metrics $ \oldMetrics -> 
    let
        oldDurationValue = 
            fromMaybe 0 $ Map.lookup actionName (callDuration oldMetrics)

        runDuration = 
            floor . nominalDiffTimeToSeconds $ 
               diffUTCTime endTime startTime
        
        newDurationValue = oldDurationValue + runDuration

    in oldMetrics {
        callDuration = 
            Map.insert actionName newDurationValue $
              callDuration oldMetrics}

    pure result

Code does not compile, throws this error:

The function ‘oldMetrics
{callDuration = Map.insert actionName newDurationValue
$ callDuration oldMetrics}’
is applied to two value arguments,
but its type ‘AppMetrics’ has none

Not able to figure out the problem.

Most Liked

billboswell

billboswell

That did the trick. Amen to fixup on dangling code lines. Loving the book. Thx for speedy reply!

Where Next?

Popular Pragmatic Bookshelf topics Top

sdmoralesma
Title: Web Development with Clojure, Third Edition - migrations/create not working: p159 When I execute the command: user=&gt; (create-...
New
mikecargal
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
raul
Hi Travis! Thank you for the cool book! :slight_smile: I made a list of issues and thought I could post them chapter by chapter. I’m rev...
New
New
nicoatridge
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
adamwoolhether
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
digitalbias
Title: Build a Weather Station with Elixir and Nerves: Problem connecting to Postgres with Grafana on (page 64) If you follow the defau...
New
jwandekoken
Book: Programming Phoenix LiveView, page 142 (157/378), file lib/pento_web/live/product_live/form_component.ex, in the function below: d...
New
gorkaio
root_layout: {PentoWeb.LayoutView, :root}, This results in the following following error: no “root” html template defined for PentoWeb...
New
mcpierce
@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

Other popular topics Top

New
PragmaticBookshelf
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
brentjanderson
Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New
AstonJ
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
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
AstonJ
I have seen the keycaps I want - they are due for a group-buy this week but won’t be delivered until October next year!!! :rofl: The Ser...
New
DevotionGeo
The V Programming Language Simple language for building maintainable programs V is already mentioned couple of times in the forum, but I...
New
PragmaticBookshelf
Author Spotlight Jamis Buck @jamis This month, we have the pleasure of spotlighting author Jamis Buck, who has written Mazes for Prog...
New
hilfordjames
There appears to have been an update that has changed the terminology for what has previously been known as the Taskbar Overflow - this h...
New
PragmaticBookshelf
Author Spotlight: Peter Ullrich @PJUllrich Data is at the core of every business, but it is useless if nobody can access and analyze ...
New

Sub Categories: