What is the showS trick in Haskell? - haskell

I have seen references to the showS trick to build strings (e.g., in this discussion), but I have never seen a good description of it.
What is the showS trick?

In the standard library, ShowS is defined as:
type ShowS = String -> String
This is a difference list.
The trick is that a string xs is represented as a ShowS by the function that prepends it to any other list: (xs ++). This allows efficient concatenation, avoiding the problems of nested left-associative concatenation (i.e. ((as ++ bs) ++ cs) ++ ds). For example:
hello = ("hello" ++)
world = ("world" ++)
-- We can "concatenate" ShowS values simply by composing them:
helloworld = hello . world
-- and turn them into Strings by passing them an empty list:
helloworld' = helloworld ""
It's called ShowS because it's used in the implementation of the standard Show typeclass to allow efficient showing of large, deeply-nested structures; as well as show, you can implement showsPrec, which has the type:
showsPrec :: (Show a) => Int -> a -> ShowS
This allows handling of operator precedence, and returns a ShowS value. The standard instances implement this instead of show for efficiency; show a is then defined in terms of it, as showsPrec 0 a "". (This default definition is in the Show typeclass itself, so you can just implement showsPrec for a complete instance.)

showS uses the difference list approach to efficiently concatenate individual components of the shown value. The function takes the value to be shown, and a string to append to the result. The appended string is passed all the way down to the right-most sub-value until it reaches a leaf, where it is actually appended.
There's a description of difference lists (including showS) here http://www.haskell.org/haskellwiki/Difference_list

Related

Indent all lines in a string

I have some types with custom Show instances defined. They are structured like this:
data TopLevel = TopLevel SndLevel
data SndLevel = SndLevel Int
instance Show SndLevel where
show (SndLevel i) = "SndLevel: \n\t" ++ (show i)
My Show instance for SndLevel produces nice looking strings that look like the following when they appear in my output:
SndLevel:
5
I would like to create a Show instance for topLevel that causes TopLevel (SndLevel 5) to look like this when printed to the terminal:
TopLevel
SndLevel
5
I was hoping to find a function built into Haskell that would add "\t" at the front of a string and before each location where "\n" appears in that string.
The best solution I found would go along the lines of the answer in this post. In this case, I would replace "\n" with "\t\n".
I assume I'm not the first person to need Show instances for hierarchically organized data in Haskell, so I would like to know if there is a more idiomatic way to get this done. Is there some better solution to my problem?
p.s: I realize this kind of printing is not the best for the example datatypes I use above. The real datatypes I want to write instances for are product types, and so they don't read well when stretched out on one line. With that in mind, if there is a popular way to deal with this kind of problem without newlines and tabs, that could also solve my problem.
We can solve this by using lines :: String -> [String] and unlines :: [String] -> String to move from a String to a list of Strings and back.
In between, we can make use of map :: (a -> b) -> [a] -> [b] to prepend all lines (a String is a list of Chars) with a tab, like:
indent :: String -> String
indent = unlines . map ('\t' :) . lines
For example:
Prelude> indent (show (SndLevel 5))
"\tSndLevel: \n\t\t5\n"
We can use this in our defintion of Show for both SndLevel and TopLevel like:
instance Show SndLevel where
show (SndLevel n) = "SndLevel:" ++ '\n' : indent (show n)
instance Show TopLevel where
show (TopLevel n) = "TopLevel:" ++ '\n' : indent (show n)
This thus gives us:
Prelude> print (TopLevel (SndLevel 5))
TopLevel:
SndLevel:
5
That being said, a Show is usually used to show a representation of the object that can usually be "injected" back inh the compiler/interpreter. The idea of using indentation is not bad at all, but perhaps it makes sence to define your own typeclass for that. You could make that typeclass more efficient by using a parameter that is passed and updated, that keeps track of the indentation level.
There are furthermore several "pretty printing" libraries [Reddit] that can print the structure of an object nicely. So instead of "reinventing the wheel", it might be worth using one of the packages listed on the Reddit page.

Haskell: Runtime Data Type Iteration?

A friend and I have been working on a system for automatically importing C functions into GNU Guile, but need to use Haskell's C parser because no other parser seems sufficient or as accessible (let me know if we're wrong about that).
The trouble is coming up when we try to produce Scheme data from the parsed AST. We need to produce text that can be directly imported by scheme (S-Expressions, not M-Expressions), so below is an example...
toscm $ Just (SomeType (AnotherType "test" 5) (YetAnother "hello!"))
=> "(Just (SomeType (AnotherType \"test\" 5) (YetAnother \"hello!\")))"
The output of Haskell's C parser has type (Either ParseError CTranslUnit). CTranslUnit is a specialization (CTranslationUnit NodeInfo). The CTranslationUnit's contents have ever more contents going deeper than is really any fun at all.
Before realizing that, I tried the following...
class Schemable a where
toscm :: a -> String
{- and then an (omitted) ridiculously (1000+ lines) long chain
of horrible instance declarations for every single type
that can be part of the C AST -}
I figured there really must be a better way to do this, but I haven't been able to find one I understand. GHC.Generics seems like it might have a solution, but the semantics of some of its internal types baffles me.
What should I do??
Update: I've been looking into Scrap Your Boilerplate, and while it definitely looks good for finding substructures, it doesn't provide a way for me to generically convert data to strings. The ideal would be if the data with the constructor Maybe (CoolType "awesome" (Something "funny")) could be processed with a function that would give me access to the names of the constructors, and allow me to recurse on the values of the arguments to that constructor. e.g...
data Constructorized = Constructed String [Constructorized]
| RawValue <anything>
constructorize :: <anything> -> Constructorized
constructorize a = <???>
toscm :: Constructorized -> String
toscm (Constructed c v) = "(" ++ c ++ " " ++ (intercalate " " (map toscm v)) ++ ")"
toscm (RawValue v) = show v
I guess the train of thought I'm on is: Show seems to be able to recurse into every single type that derives it, no problem. How are the functions for that generated? Shouldn't we be able to make our own Show that generates similar functions, with a slightly different output?

Why can't I use the type `Show a => [Something -> a]`?

I have a record type say
data Rec {
recNumber :: Int
, recName :: String
-- more fields of various types
}
And I want to write a toString function for Rec :
recToString :: Rec -> String
recToString r = intercalate "\t" $ map ($ r) fields
where fields = [show . recNumber, show . recName]
This works. fields has type [Rec -> String]. But I'm lazy and I would prefer writing
recToString r = intercalate "\t" $ map (\f -> show $ f r) fields
where fields = [recNumber, recName]
But this doesn't work. Intuitively I would say fields has type Show a => [Rec -> a] and this should be ok. But Haskell doesn't allow it.
I'd like to understand what is going on here. Would I be right if I said that in the first case I get a list of functions such that the 2 instances of show are actually not the same function, but Haskell is able to determine which is which at compile time (which is why it's ok).
[show . recNumber, show . recName]
^-- This is show in instance Show Number
^-- This is show in instance Show String
Whereas in the second case, I only have one literal use of show in the code, and that would have to refer to multiple instances, not determined at compile time ?
map (\f -> show $ f r) fields
^-- Must be both instances at the same time
Can someone help me understand this ? And also are there workarounds or type system expansions that allow this ?
The type signature doesn't say what you think it says.
This seems to be a common misunderstanding. Consider the function
foo :: Show a => Rec -> a
People frequently seem to think this means that "foo can return any type that it wants to, so long as that type supports Show". It doesn't.
What it actually means is that foo must be able to return any possible type, because the caller gets to choose what the return type should be.
A few moments' thought will reveal that foo actually cannot exist. There is no way to turn a Rec into any possible type that can ever exist. It can't be done.
People often try to do something like Show a => [a] to mean "a list of mixed types but they all have Show". That obviously doesn't work; this type actually means that the list elements can be any type, but they still have to be all the same.
What you're trying to do seems reasonable enough. Unfortunately, I think your first example is about as close as you can get. You could try using tuples and lenses to get around this. You could try using Template Haskell instead. But unless you've got a hell of a lot of fields, it's probably not even worth the effort.
The type you actually want is not:
Show a => [Rec -> a]
Any type declaration with unbound type variables has an implicit forall. The above is equivalent to:
forall a. Show a => [Rec -> a]
This isn't what you wan't, because the a must be specialized to a single type for the entire list. (By the caller, to any one type they choose, as MathematicalOrchid points out.) Because you want the a of each element in the list to be able to be instantiated differently... what you are actually seeking is an existential type.
[exists a. Show a => Rec -> a]
You are wishing for a form of subtyping that Haskell does not support very well. The above syntax is not supported at all by GHC. You can use newtypes to sort of accomplish this:
{-# LANGUAGE ExistentialQuantification #-}
newtype Showy = forall a. Show a => Showy a
fields :: [Rec -> Showy]
fields = [Showy . recNumber, Showy . recName]
But unfortunatley, that is just as tedious as converting directly to strings, isn't it?
I don't believe that lens is capable of getting around this particular weakness of the Haskell type system:
recToString :: Rec -> String
recToString r = intercalate "\t" $ toListOf (each . to fieldShown) fields
where fields = (recNumber, recName)
fieldShown f = show (f r)
-- error: Couldn't match type Int with [Char]
Suppose the fields do have the same type:
fields = [recNumber, recNumber]
Then it works, and Haskell figures out which show function instance to use at compile time; it doesn't have to look it up dynamically.
If you manually write out show each time, as in your original example, then Haskell can determine the correct instance for each call to show at compile time.
As for existentials... it depends on implementation, but presumably, the compiler cannot determine which instance to use statically, so a dynamic lookup will be used instead.
I'd like to suggest something very simple instead:
recToString r = intercalate "\t" [s recNumber, s recName]
where s f = show (f r)
All the elements of a list in Haskell must have the same type, so a list containing one Int and one String simply cannot exist. It is possible to get around this in GHC using existential types, but you probably shouldn't (this use of existentials is widely considered an anti-pattern, and it doesn't tend to perform terribly well). Another option would be to switch from a list to a tuple, and use some weird stuff from the lens package to map over both parts. It might even work.

How to access nth element in a Haskell tuple

I have this:
get3th (_,_,a,_,_,_) = a
which works fine in GHCI but I want to compile it with GHC and it gives error. If I want to write a function to get the nth element of a tuple and be able to run in GHC what should I do?
my all program is like below, what should I do with that?
get3th (_,_,a,_,_,_) = a
main = do
mytuple <- getLine
print $ get3th mytuple
Your problem is that getLine gives you a String, but you want a tuple of some kind. You can fix your problem by converting the String to a tuple – for example by using the built-in read function. The third line here tries to parse the String into a six-tuple of Ints.
main = do
mystring <- getLine
let mytuple = read mystring :: (Int, Int, Int, Int, Int, Int)
print $ get3th mytuple
Note however that while this is useful for learning about types and such, you should never write this kind of code in practise. There are at least two warning signs:
You have a tuple with more than three or so elements. Such a tuple is very rarely needed and can often be replaced by a list, a vector or a custom data type. Tuples are rarely used more than temporarily to bring two kinds of data into one value. If you start using tuples often, think about whether or not you can create your own data type instead.
Using read to read a structure is not a good idea. read will explode your program with a terrible error message at any tiny little mistake, and that's usually not what you want. If you need to parse structures, it's a good idea to use a real parser. read can be enough for simple integers and such, but no more than that.
The type of getLine is IO String, so your program won't type check because you are supplying a String instead of a tuple.
Your program will work if proper parameter is supplied, i.e:
main = do
print $ get3th (1, 2, 3, 4, 5, 6)
It seems to me that your confusion is between tuples and lists. That is an understandable confusion when you first meet Haskell as many other languages only have one similar construct. Tuples use round parens: (1,2). A tuple with n values in it is a type, and each value can be a different type which results in a different tuple type. So (Int, Int) is a different type from (Int, Float), both are two tuples. There are some functions in the prelude which are polymorphic over two tuples, ie fst :: (a,b) -> a which takes the first element. fst is easy to define using pattern matching like your own function:
fst (a,b) = a
Note that fst (1,2) evaluates to 1, but fst (1,2,3) is ill-typed and won't compile.
Now, lists on the other hand, can be of any length, including zero, and still be the same type; but each element must be of the same type. Lists use square brackets: [1,2,3]. The type for a list with elements of type a is written [a]. Lists are constructed from appending values onto the empty list [], so a list with one element can be typed [a], but this is syntactic sugar for a:[], where : is the cons operator which appends a value to the head of the list. Like tuples can be pattern matched, you can use the empty list and the cons operator to pattern match:
head :: [a] -> a
head (x:xs) = x
The pattern match means x is of type a and xs is of type [a], and it is the former we want for head. (This is a prelude function and there is an analogous function tail.)
Note that head is a partial function as we cannot define what it does in the case of the empty list. Calling it on an empty list will result in a runtime error as you can check for yourself in GHCi. A safer option is to use the Maybe type.
safeHead :: [a] -> Maybe a
safeHead (x:xs) = Just x
safeHead [] = Nothing
String in Haskell is simply a synonym for [Char]. So all of these list functions can be used on strings, and getLine returns a String.
Now, in your case you want the 3rd element. There are a couple of ways you could do this, you could call tail a few times then call head, or you could pattern match like (a:b:c:xs). But there is another utility function in the prelude, (!!) which gets the nth element. (Writing this function is a very good beginner exercise). So your program can be written
main = do
myString <- getLine
print $ myString !! 2 --zero indexed
Testing gives
Prelude> main
test
's'
So remember, tuples us ()and are strictly of a given length, but can have members of different types; whereas lists use '[]', can be any length, but each element must be the same type. And Strings are really lists of characters.
EDIT
As an aside, I thought I'd mention that there is a neater way of writing this main function if you are interested.
main = getLine >>= print . (!!3)

How do you customize the Show instance for a Haskell record?

I have a Haskell record data type that looks like this:
data Client = Client { clientId :: Int
, nickname :: Text
, clientSink :: Maybe (WS.Sink WS.Hybi00)
, clientRoom :: Maybe Room
}
I can't derive a Show instance from this because of WS.Sink has no Show instance.
How can I make a Show instance that excludes just the clientSink field, but prints the rest of the record fields like a normal record?
Should I just create a custom Show instance for WS.Sink?
Add a Show instance for WS.Sink
instance Show WS.Sink where show a = "Sink"
or whatever dummy value you want.
I'm not sure you really want an instance of Show, in this case. From the docs.
Derived instances of Show have the following properties, which are compatible with derived instances of Read:
The result of show is a syntactically correct Haskell expression containing only constants, given the fixity declarations in force at the point where the type is declared. It contains only the constructor names defined in the data type, parentheses, and spaces. When labelled constructor fields are used, braces, commas, field names, and equal signs are also used.
This does come with the caveat that it applies only to derived instances, but I'm a stickler for contracts, and have gotten used to assuming that read . show is effectively a no-op. You'd run into this same problem again when trying to automatically derive an instance for Read of course, so it's not like you would be introducing a semantic error by using Show now, it's just a matter of preference.
Depending on your context (taking a wild guess, you're trying to debug by printing intermediate values somewhere?) defining another typeclass and implementing a toString-like function might work best for you without being potentially misleading as to the show functionality of your instance. E.g.,
class ToString a where
toString :: a -> String
instance ToString Client where
toString c = "Client {"
++ shows (clientId c) ", "
++ shows (nickname c) ", "
++ shows (isJust (clientSink c)) ", "
++ show (clientRoom c)
++ "}"
And then if you wanted to turn this into a Show instance it's as simple as
instance Show Client where
show = toString

Resources