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

jimmykiang
This test is broken right out of the box… — FAIL: TestAgent (7.82s) agent_test.go:77: Error Trace: agent_test.go:77 agent_test.go:...
New
johnp
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’. In particula...
New
ianwillie
Hello Brian, I have some problems with running the code in your book. I like the style of the book very much and I have learnt a lot as...
New
mikecargal
Title: Hands-On Rust (Chapter 11: prefab) Just played a couple of amulet-less games. With a bit of debugging, I believe that your can_p...
New
jdufour
Hello! On page xix of the preface, it says there is a community forum "… for help if your’re stuck on one of the exercises in this book… ...
New
mikecargal
Title: Hands-on Rust: question about get_component (page 295) (feel free to respond. “You dug you’re own hole… good luck”) I have somet...
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
adamwoolhether
I’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
New
jskubick
I found an issue in Chapter 7 regarding android:backgroundTint vs app:backgroundTint. How to replicate: load chapter-7 from zipfile i...
New
akraut
The markup used to display the uploaded image results in a Phoenix.LiveView.HTMLTokenizer.ParseError error. lib/pento_web/live/product_l...
New

Other popular topics Top

New
PragmaticBookshelf
Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that u...
New
AstonJ
There’s a whole world of custom keycaps out there that I didn’t know existed! Check out all of our Keycaps threads here: https://forum....
New
AstonJ
I’ve been hearing quite a lot of comments relating to the sound of a keyboard, with one of the most desirable of these called ‘thock’, he...
New
AstonJ
Do the test and post your score :nerd_face: :keyboard: If possible, please add info such as the keyboard you’re using, the layout (Qw...
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 Mike Riley @mriley This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
New
PragmaticBookshelf
Author Spotlight Rebecca Skinner @RebeccaSkinner Welcome to our latest author spotlight, where we sit down with Rebecca Skinner, auth...
New
AstonJ
If you want a quick and easy way to block any website on your Mac using Little Snitch simply… File &gt; New Rule: And select Deny, O...
New
CommunityNews
Open-source implementation of the classic GTA engine now running directly in your browser. Experience the reVC technology demo on DOS.Zon...
New

Sub Categories: