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

jon
Some minor things in the paper edition that says “3 2020” on the title page verso, not mentioned in the book’s errata online: p. 186 But...
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
AleksandrKudashkin
On the page xv there is an instruction to run bin/setup from the main folder. I downloaded the source code today (12/03/21) and can’t see...
New
leba0495
Hello! Thanks for the great book. I was attempting the Trie (chap 17) exercises and for number 4 the solution provided for the autocorre...
New
Charles
In general, the book isn’t yet updated for Phoenix version 1.6. On page 18 of the book, the authors indicate that an auto generated of ro...
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
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
dachristenson
@mfazio23 Android Studio will not accept anything I do when trying to use the Transformations class, as described on pp. 140-141. Googl...
New
dachristenson
I’ve got to the end of Ch. 11, and the app runs, with all tabs displaying what they should – at first. After switching around between St...
New

Other popular topics Top

AstonJ
You might be thinking we should just ask who’s not using VSCode :joy: however there are some new additions in the space that might give V...
New
New
AstonJ
This looks like a stunning keycap set :orange_heart: A LEGENDARY KEYBOARD LIVES ON When you bought an Apple Macintosh computer in the e...
New
Exadra37
Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New
PragmaticBookshelf
Programming Ruby is the most complete book on Ruby, covering both the language itself and the standard library as well as commonly used t...
New
PragmaticBookshelf
Leverage Elixir and the Nx ecosystem to build intelligent applications that solve real-world problems in computer vision, natural languag...
New
PragmaticBookshelf
Get the comprehensive, insider information you need for Rails 8 with the new edition of this award-winning classic. Sam Ruby @rubys ...
New
AstonJ
This is a very quick guide, you just need to: Download LM Studio: https://lmstudio.ai/ Click on search Type DeepSeek, then select the o...
New
PragmaticBookshelf
A concise guide to MySQL 9 database administration, covering fundamental concepts, techniques, and best practices. Neil Smyth MySQL...
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: