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

belgoros
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84: bundle exec sequel...
New
Alexandr
Hi everyone! There is an error on the page 71 in the book “Programming machine learning from coding to depp learning” P. Perrotta. You c...
New
JohnS
I can’t setup the Rails source code. This happens in a working directory containing multiple (postgres) Rails apps. With: ruby-3.0.0 s...
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
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
brunogirin
When running tox for the first time, I got the following error: ERROR: InterpreterNotFound: python3.10 I realised that I was running ...
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
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
ggerico
I got this error when executing the plot files on macOS Ventura 13.0.1 with Python 3.10.8 and matplotlib 3.6.1: programming_ML/code/03_...
New
bjnord
Hello @herbert ! Trying to get the very first “Hello, Bracket Terminal!" example to run (p. 53). I develop on an Amazon EC2 instance runn...
New

Other popular topics Top

AstonJ
If it’s a mechanical keyboard, which switches do you have? Would you recommend it? Why? What will your next keyboard be? Pics always w...
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
AstonJ
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
AstonJ
If you’re getting errors like this: psql: error: connection to server on socket “/tmp/.s.PGSQL.5432” failed: No such file or directory ...
New
AnfaengerAlex
Hello, I’m a beginner in Android development and I’m facing an issue with my project setup. In my build.gradle.kts file, I have the foll...
New
mindriot
Ok, well here are some thoughts and opinions on some of the ergonomic keyboards I have, I guess like mini review of each that I use enoug...
New
PragmaticBookshelf
This book forgoes the abstract and instead provides concrete examples to help you better leverage the unique properties of Elixir, Erlang...
New
PragmaticBookshelf
As digital systems increasingly run the world, mastery of the recurring patterns of software development risk is the key to fast and effe...
New
PragmaticBookshelf
Lint your docs like code: turn any style guide into enforceable rules with Vale and publish clear, consistent content every time. ...
New
PragmaticBookshelf
Write elegant Ruby code—not just correct, but idiomatic. Go beyond the vocabulary and syntax and learn to express yourself with eloquence...
New

Sub Categories: