andre

andre

Effective Haskell: Observation - Chapter 15 - associated data families (B9 - PDF version)

I’m hopeful for someone that could explain what GHCI does to differentiate an IO action returning a value that has a Show instance versus another IO action returning a value that does not.

Is this difference in behavior related to using associated data families ?

Here is the context that brought this question.

Chapter 15, in the section "Associated Data Families.

On p.574, we find the instance definition of ListDirectory.
Note that the associated data family has a deriving clause.

instance ShellCommand ListDirectory where
    data ShellOutput ListDirectory = 
        DirectoryListing 
          { containingDirectory :: FilePath
          , filenamesInListing :: [FilePath]
          } deriving (Show, Eq)

At the ghci prompt, when you run either of these commands, you get some output.
With the first command, you get a list of values. With the second command, you get a DirectoryListing. Make sense, we have derived a Show instance.

λ> directoryListingWithParent <$> runShellCommand (ListDirectory ".")
[ "./app", "./CHANGELOG.md", "./dist-newstyle",  ... ]

λ> runShellCommand (ListDirectory ".")
DirectoryListing
    { containingDirectory = "."
    , filenamesInListing = [ "app" , "CHANGELOG.md", "dist-newstyle", ...  ]
    }


Moving on to the following page, we find the instance definition of Grep.
Note that the associated data family does NOT have a deriving clause

instance ShellCommand Grep where
    newtype ShellOutput Grep =
        ListOfGrepMatches { getListOfGrepMatches :: [GrepMatch] }

At the GHCI prompt, when you run this command, you do NOT get any output
This makes sense since we have no Show instance. However, why not throwing an error ?

λ> runShellCommand (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"])

I’m not sure if what I’m about to say is correct. I suspect that GHCI understands that there is no Show instance.

λ> :t runShellCommand (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"])
runShellCommandV3 (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"])
  :: IO (ShellOutput Grep)
λ> putStrLn . show <$> runShellCommand (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"])

    <interactive>:45:12: error: [GHC-39999]
        • No instance for ‘Show (ShellOutput Grep)’
            arising from a use of ‘show’

If you add the deriving clause, the command returns some output.

instance ShellCommand Grep where
    newtype ShellOutput Grep =
        ListOfGrepMatches { getListOfGrepMatches :: [GrepMatch] }
           deriving Show

-- Same type as the above example, which produces not output
λ> :t (runShellCommand (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"]))
(runShellCommandV3 (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"]))
  :: IO (ShellOutput Grep)


λ> runShellCommand (Grep "version" ["./effectiveHaskell.cabal", "./CHANGELOG.md"])`

    ListOfGrepMatches
        { getListingOfGrepMatches =
            [ GrepMatch
                { grepMatchingFileName = "./effectiveHaskell.cabal"
                , grepMatchingLineNumber = 1
                , grepMatchingLineContents = "cabal-version:      2.4"
                }
   << rest of output truncated >>

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
brianokken
Many tasks_proj/tests directories exist in chapters 2, 3, 5 that have tests that use the custom markers smoke and get, which are not decl...
New
Mmm
Hi, build fails on: bracket-lib = “~0.8.1” when running on Mac Mini M1 Rust version 1.5.0: Compiling winit v0.22.2 error[E0308]: mi...
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
jskubick
I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to buil...
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
brunogirin
When installing Cards as an editable package, I get the following error: ERROR: File “setup.py” not found. Directory cannot be installe...
New
brunogirin
When running tox for the first time, I got the following error: ERROR: InterpreterNotFound: python3.10 I realised that I was running ...
New
taguniversalmachine
It seems the second code snippet is missing the code to set the current_user: current_user: Accounts.get_user_by_session_token(session["...
New
davetron5000
Hello faithful readers! If you have tried to follow along in the book, you are asked to start up the dev environment via dx/build and ar...
New

Other popular topics Top

PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
PragmaticBookshelf
Brace yourself for a fun challenge: build a photorealistic 3D renderer from scratch! In just a couple of weeks, build a ray tracer that r...
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
Rainer
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
Exadra37
I am asking for any distro that only has the bare-bones to be able to get a shell in the server and then just install the packages as we ...
New
AstonJ
In case anyone else is wondering why Ruby 3 doesn’t show when you do asdf list-all ruby :man_facepalming: do this first: asdf plugin-upd...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
PragmaticBookshelf
Author Spotlight Rebecca Skinner @RebeccaSkinner Welcome to our latest author spotlight, where we sit down with Rebecca Skinner, auth...
New
First poster: bot
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig. General-purpose programming language and toolchain for maintaini...
New
Fl4m3Ph03n1x
Background Lately I am in a quest to find a good quality TTS ai generation tool to run locally in order to create audio for some videos I...
New

Sub Categories: