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