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
That did the trick. Amen to fixup on dangling code lines. Loving the book. Thx for speedy reply!
Popular Pragmatic Bookshelf topics
                        
                      
                      Other popular topics
                        
                      
                      Categories:
Sub Categories:
Popular Portals
- /elixir
 - /rust
 - /ruby
 - /wasm
 - /erlang
 - /phoenix
 - /keyboards
 - /python
 - /rails
 - /js
 - /security
 - /go
 - /swift
 - /vim
 - /clojure
 - /haskell
 - /emacs
 - /java
 - /svelte
 - /onivim
 - /typescript
 - /kotlin
 - /c-plus-plus
 - /crystal
 - /tailwind
 - /react
 - /gleam
 - /ocaml
 - /elm
 - /flutter
 - /vscode
 - /ash
 - /html
 - /opensuse
 - /centos
 - /php
 - /zig
 - /deepseek
 - /scala
 - /lisp
 - /textmate
 - /sublime-text
 - /react-native
 - /nixos
 - /debian
 - /agda
 - /kubuntu
 - /arch-linux
 - /django
 - /deno
 - /revery
 - /ubuntu
 - /manjaro
 - /nodejs
 - /spring
 - /diversity
 - /lua
 - /julia
 - /slackware
 - /c
 
    





