An instance of a type class is not used when retrieving a data structure

I studied the use of more newtypewrappers in my code to create more different types. I also do a lot of cheap serialization using Read / Show, especially as a simple form of a strongly typed configuration file. Today I came across this:

The example starts this way, and I define a simple new type to wrap around Int along with a named expand field:

module Main where

import Debug.Trace ( trace )
import Text.Read ( readEither )


newtype Bar = Bar { unBar :: Int }
   deriving Show

A user instance to read one of them from the simple Int syntax. The idea here is that it would be great if you could put "42" in the configuration file instead of "Bar {unBar = 42}"

"logging", , .

instance Read Bar where
   readsPrec _ s = [(Bar i, "")]
      where i = read (trace ("[debug \"" ++ s ++ "\"]") s)

, . Read.

data Foo = Foo { bar :: Bar }
   deriving (Read, Show)


main :: IO ()
main = do

Read

   print $ ((readEither "42") :: Either String Bar)
   putStrLn ""

- Foo, Bar Read, Bar! ( , )

   print $ ((readEither "Foo { bar = 42 }") :: Either String Foo)
   putStrLn ""

, , ?

   print $ ((readEither "Foo { bar = Bar { unBar = 42 } }") :: Either String Foo)

! ! , .

:

  $ stack exec readbug
  [debug "42"]
  Right (Bar {unBar = 42})

  Left "Prelude.read: no parse"

  Left "Prelude.read: no parse"

, , .

. src/Main.lhs darcshub

+4
1

Read. readsPrec , Bar -. :

readsPrec d s , (<parsed value>, <remaining string>). , .

:

instance Read Bar where
   readsPrec d s = [ (Bar i, s') | (i, s') <- readsPrec d tracedS ]
      where tracedS = trace ("[debug \"" ++ s ++ "\"]") s

:

ghci> print $ ((readEither "Foo { bar = 42 }") :: Either String Foo)
[debug " 42 }"]
Right (Foo {bar = Bar {unBar = 42}})

, :

, , ?

 print $ ((readEither "Foo { bar = Bar { unBar = 42 } }") :: Either String Foo)

- : Read Bar, read . show . Foo Read, Bar Read ( , Bar , Read).

+4

Source: https://habr.com/ru/post/1663902/


All Articles