Haskell, documentation for unlabeled command line arguments in optparse-generic - haskell

I'm using optparse-generic to parse the command line arguments of a program called example. I have a datatype with an unnamed field. For example:
data Unlabeled = Unlabeled String deriving (Generic, Show)
This generates a program which can be called as follows: ./exmaple "foo". However, for the user, there is no documentation what the String-parameter is about. In particular, ./example --help does not give any valuable information about this positional String argument ./example expects.
Using named datatypes (record syntax), it is possible to add documentation to the datatype. For example
data Labeled = Labeled {name :: String <?> "Select the foo"} deriving (Generic, Show)
This generates help text for the program. For example, when called ./example --help, it will display --name STRING Select the foo.
How can I add documentation to unnamed datatypes in the same way as I can do for record-syntax-datatypes?

data Labeled = Labeled (String <?> "Select the foo") will give you
...
STRING Select the foo
...
in the --help message. To perhaps clarify, the <?> is simply a type constructor, it is just syntactically an operator. Maybe fun fact: you can write data X = X (Int `Either` Bool) as well.

Related

Is any Atom data type in Haskell?

When I read/show String I get/expect the result to be quoted. If I want to omit quotes, I can implement some type like:
newtype Atom = Atom String deriving (Eq, Ord)
instance Read Atom where ...
instance Show Atom where ...
But my question is: does such type already exist somewhere in libraries, in the base, may be? I just found some Data.Atom but seems it something different (XML, etc).
No. If you find yourself wanting this, it means you're using Show in an unintended way. The idea of show is that is should always yield valid Haskell code. The Show String instance guarantees this, by safely quoting and escaping the contents. Short of that, you would of course in general not get Haskell code. Now, sure there are applications where you want to display something and don't care about whether it's Haskell code, but that shouldn't be show then.
Usually, if you have a string anyway, you should just use putStrLn directly.
Since Read and Show are for converting data to/from strings, you can just use the id function :)
But seriously, a String is already the output of its own read or show, if you don't want it quoted.
Say, for example, to print any other value (or a String, if you want it to appear quoted), you do:
putStrLn (show "Hello") -- prints "Hello", with quotes.
whereas, to print a string unquoted, you can simply do:
putStrLn "Hello" -- prints Hello, unquoted.
Because of this, I don't think there is any utility for this (it is trivial, after all); in fact, your Atom instances would simply be:
instance Read Atom where read = Atom
instance Show Atom where show (Atom s) = s
Depending on what you're doing, you may want to inspect the type and use print for non-strings and putStrLn for strings like this:
import Data.Typeable
printAny :: (Show a, Typeable a) => a -> IO ()
printAny a = case cast a of
Just str -> putStrLn str
Nothing -> print a
Then, as desired:
*Main> printAny "no quotes"
no quotes
*Main> printAny (10 :: Int)
10

Efficient way of printing property names in Haskell

Hello i am new to Haskell and i was wondering :
For every new defined type constructor even if it is something with 0 depth eg.:
data Letter =A | B | C deriving (Show)
do i have to provide
instance Show Type
Letter A = "A"
Letter B ="B"
Letter C ="C"
I understand that for nested types you have to provide Show implementation but for something simple is there no other way to just use something equivalent to reflection (C#) ? Just get the property name / constructor name and ToString-it ?
Do haskell programmers provide instances for Show for any adhoc type they create?
By nested types i mean having a simple ADT inside another ADT inside another etc..but all you want is to get their names:
e.g:
data Person = Male | Female
data IsMarried=Yes | No
data Worker=Worker{
person::Person,
status::IsMarried
}
For this kind of nesting do i really have to define instance of Show for all these type constructors even though all i want is their name be "stringified"?
Do I have to provide [a show instance for every type?]
No, because you have automatically derived Show:
data Letter = A | B | C deriving (Show)
-- ^^^^^^^^^^^^^^^ Here
However, if you want a 'smarter' show, such as displaying a custom list as [1,2,3] rather than a mess of constructors, you're going to have to write it yourself.
You can do the same for a number of classes (Including Eq,Ord,Read,Enum, and Bounded) but most classes, including user-defined classes, must be implemented manually without the use of certain language extensions.
I understand that for nested types you have to provide Show implementation[...]
You do not! For instance, I can write this:
data Maybe a = Just a | Nothing deriving (Show)
And the compiler will automatically add the necessary constraints, despite it being a 'nested' type.
Just get the property name / constructor name and ToString-it ?
There are no 'properties' in Haskell - don't think in terms of C# here. show is the equivalent of ToString. However, a form of type reflection is available in TypeReps, though I would advise not using this until you have a solid grasp on Haskell.
Since #AJFarmar edit back his answer when i change it:
Do I have to provide [a show instance for every type?]
Yes. Either by deriving it with deriving Show, or by supplying a type instance
instance Show -type- where...
I understand that for nested types you have to provide Show implementation[...]
Yes you do, the compiler will not add any necessary instances for Show.
data Test = Test -- no instance for Show
test :: String
test = show $ (Just Test :: Maybe Test)
Will not compile with the error message:
main.hs:4:8: error:
• No instance for (Show Test) arising from a use of ‘show’
• In the expression: show $ (Just Test :: Maybe Test)
In an equation for ‘test’: test = show $ (Just Test :: Maybe Test)
Which is why you need to have a Show instance for a aswell. If one already exists, you do not have to supply a new one, however.

Why is the restriction on newtype?

I read that "newtype has exactly one constructor with exactly one field inside it." Is this restriction adds any advantage? If the value constructor is limited with only one field, why can't i use the field directly in my code, instead of wrapping it with newtype?
newtype is a tool for creating data abstraction that has no runtime cost.
What do I mean by abstraction?
Suppose you have:
greetPerson :: String -> String -> String
greetPerson greeting name = greeting ++ " " ++ name
greetPerson "Hello" "Mike" => "Hello Mike"
This works fine, but it opens opportunities for misuse:
greetPerson "Mike" "Hello" => "Mike Hello"
The problem is that you're using the same type everywhere (String), carrying no semantic meaning. Let's use a newtype:
newtype Name = Name String
greetPerson :: String -> Name -> String
greetPerson greeting (Name name) = greeting ++ " " ++ name
greetPerson "Hello" (Name "Mike") => "Hello Mike"
We end up with the same functionality, but now the type signature carries more meaning and the compiler can tell us when we misuse it.
What do I mean by no runtime cost?
The newtype from my example exists only at the type level and the compiler generates exactly the same code as if I used String throughout.
This hints at why newtype is only allowed for one constructor with one field.
Imagine you tried to make newtype work for more than one constructor. How would you distinguish which one you have at runtime? You'd have to store some additional information.
Same with more than one field. You'd need some way to bundle two fields together.
All of them add some runtime cost which newtype promises not to do.
If you want more than one field or more than one constructor simply use data:
data Foo = Bar String | Baz Int Bool

Haskell, unnamed command line arguments for optparse-generic

I'm using optparse-generic to parse the command line arguments of a program called example. I have a datatype with named fields (record syntax). For example:
data Example = Example { foo :: Int, bar :: String } deriving (Generic, Show)
This generates a program which can be called as follows:
./example --foo 42 --bar "baz"
How can I tell optparse-generic that bar should be an unnamed, mandatory, positional command line argument. That means, I don't want to type --bar when I call example. For example, I want to call example the following:
./example --foo 42 "baz"
optparse-generic does not support generating such a parser from a single data type definition since Haskell does not support records with both labeled and unlabeled fields.
However, what you can do is generate one data type for all the labeled fields and one type for the unlabeled fields and then combine them using Applicative operations, like this:
data Labeled = Labeled { foo :: Int } deriving (Generic, Show)
instance ParseRecord Labeled
data Unlabeled = Unlabeled String deriving (Generic, Show)
instance ParseRecord Unlabeled
data Mixed = Mixed Labeled Unlabeled deriving (Show)
instance ParseRecord Mixed where
parseRecord = Mixed <$> parseRecord <*> parseRecord

When should I use record syntax for data declarations in Haskell?

Record syntax seems extremely convenient compared to having to write your own accessor functions. I've never seen anyone give any guidelines as to when it's best to use record syntax over normal data declaration syntax, so I'll just ask here.
You should use record syntax in two situations:
The type has many fields
The type declaration gives no clue about its intended layout
For instance a Point type can be simply declared as:
data Point = Point Int Int deriving (Show)
It is obvious that the first Int denotes the x coordinate and the second stands for y. But the case with the following type declaration is different (taken from Learn You a Haskell for Great Good):
data Person = Person String String Int Float String String deriving (Show)
The intended type layout is: first name, last name, age, height, phone number, and favorite ice-cream flavor. But this is not evident in the above declaration. Record syntax comes handy here:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
, height :: Float
, phoneNumber :: String
, flavor :: String
} deriving (Show)
The record syntax made the code more readable, and saved a great deal of typing by automatically defining all the accessor functions for us!
In addition to complex multi-fielded data, newtypes are often defined with record syntax. In either of these cases, there aren't really any downsides to using record syntax, but in the case of sum types, record accessors usually don't make sense. For example:
data Either a b = Left { getLeft :: a } | Right { getRight :: b }
is valid, but the accessor functions are partial – it is an error to write getLeft (Right "banana"). For that reason, such accessors are generally speaking discouraged; something like getLeft :: Either a b -> Maybe a would be more common, and that would have to be defined manually. However, note that accessors can share names:
data Item = Food { description :: String, tastiness :: Integer }
| Wand { description :: String, magic :: Integer }
Now description is total, although tastiness and magic both still aren't.

Resources