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

jimschubert
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
New
adamwoolhether
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
leonW
I ran this command after installing the sample application: $ cards add do something --owner Brian And got a file not found error: Fil...
New
curtosis
Running mix deps.get in the sensor_hub directory fails with the following error: ** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New
taguniversalmachine
Hi, I am getting an error I cannot figure out on my test. I have what I think is the exact code from the book, other than I changed “us...
New
s2k
Hi all, currently I wonder how the Tailwind colours work (or don’t work). For example, in app/views/layouts/application.html.erb I have...
New
rainforest
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels. Before ...
New
mert
AWDWR 7, page 152, page 153: Hello everyone, I’m a little bit lost on the hotwire part. I didn’t fully understand it. On page 152 @rub...
New
a.zampa
@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

Other popular topics Top

New
PragmaticBookshelf
Free and open source software is the default choice for the technologies that run our world, and it’s built and maintained by people like...
New
New
AstonJ
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face: Perhaps if there’s enough peop...
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
New
PragmaticBookshelf
Tailwind CSS is an exciting new CSS framework that allows you to design your site by composing simple utility classes to create complex e...
New
AstonJ
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
PragmaticBookshelf
Author Spotlight: VM Brasseur @vmbrasseur We have a treat for you today! We turn the spotlight onto Open Source as we sit down with V...
New
DevotionGeo
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

Sub Categories: