Is there a auto-conversion from String to ByteString? - haskell

addRequestHeader (H.hContentType, "application/json")
this is a example of the usage of Network.HTTP.Simple package, i have seen a couple of times. how does that work to pass a String to that function as its signature is:
addRequestHeader :: Network.HTTP.Types.Header.HeaderName
-> Data.ByteString.Internal.ByteString -> Request -> Request
when i try this, i get the error couldn't match expected type ‘C8.ByteString’ with actual type ‘[Char]’, so i have to use Data.ByteString.Char8.pack function to make this work. why don't the others have to do that? is there a auto-convertion or whats going on here?

There is an "autoconversion" for string literals, i.e. for those strings given explicitly between quotes "...", like your "application/json".
To turn it on you need the OverloadedStrings extension.
Other string expressions (e.g., variables of type String, return values of functions, ...) will not be automatically converted.

Related

How does Haskell know whether a data type declaration is a variable or a named type?

Take a data type declaration like
data myType = Null | Container TypeA v
As I understand it, Haskell would read this as myType coming in two different flavors. One of them is Null which Haskell interprets just as some name of a ... I guess you'd call it an instance of the type? Or a subtype? Factor? Level? Anyway, if we changed Null to Nubb it would behave in basically the same way--Haskell doesn't really know anything about null values.
The other flavor is Container and I would expect Haskell to read this as saying that the Container flavor takes two fields, TypeA and v. I expect this is because, when making this type definition, the first word is always read as the name of the flavor and everything that follows is another field.
My question (besides: did I get any of that wrong?) is, how does Haskell know that TypeA is a specific named type rather than an un-typed variable? Am I wrong to assume that it reads v as an un-typed variable, and if that's right, is it because of the lower-case initial letter?
By un-typed I mean how the types appear in the following type-declaration for a function:
func :: a -> a
func a = a
First of all, terminology: "flavors" are called "cases" or "constructors". Your type has two cases - Null and Container.
Second, what you call "untyped" is not really "untyped". That's not the right way to think about it. The a in declaration func :: a -> a does not mean "untyped" the same way variables are "untyped" in JavaScript or Python (though even that is not really true), but rather "whoever calls this function chooses the type". So if I call func "abc", then I have chosen a to be String, and now the compiler knows that the result of this call must also be String, since that's what the func's signature says - "I take any type you choose, and I return the same type". The proper term for this is "generic".
The difference between "untyped" and "generic" is that "untyped" is free-for-all, the type will only be known at runtime, no guarantees whatsoever; whereas generic types, even though not precisely known yet, still have some sort of relationship between them. For example, your func says that it returns the same type it takes, and not something random. Or for another example:
mkList :: a -> [a]
mkList a = [a]
This function says "I take some type that you choose, and I will return a list of that same type - never a list of something else".
Finally, your myType declaration is actually illegal. In Haskell, concrete types have to be Capitalized, while values and type variables are javaCase. So first, you have to change the name of the type to satisfy this:
data MyType = Null | Container TypeA v
If you try to compile this now, you'll still get an error saying that "Type variable v is unknown". See, Haskell has decided that v must be a type variable, and not a concrete type, because it's lower case. That simple.
If you want to use a type variable, you have to declare it somewhere. In function declaration, type variables can just sort of "appear" out of nowhere, and the compiler will consider them "declared". But in a type declaration you have to declare your type variables explicitly, e.g.:
data MyType v = Null | Container TypeA v
This requirement exist to avoid confusion and ambiguity in cases where you have several type variables, or when type variables come from another context, such as a type class instance.
Declared this way, you'll have to specify something in place of v every time you use MyType, for example:
n :: MyType Int
n = Null
mkStringContainer :: TypeA -> String -> MyType String
mkStringContainer ta s = Container ta s
-- Or make the function generic
mkContainer :: TypeA -> a -> MyType a
mkContainer ta a = Container ta a
Haskell uses a critically important distinction between variables and constructors. Variables begin with a lower-case letter; constructors begin with an upper-case letter1.
So data myType = Null | Container TypeA v is actually incorrect; the first symbol after the data keyword is the name of the new type constructor you're introducing, so it must start with a capital letter.
Assuming you've fixed that to data MyType = Null | Container TypeA v, then each of the alternatives separated by | is required to consist of a data constructor name (here you've chosen Null and Container) followed by a type expression for each of the fields of that constructor.
The Null constructor has no fields. The Container constructor has two fields:
TypeA, which starts with a capital letter so it must be a type constructor; therefore the field is of that concrete type.
v, which starts with a lowercase letter and is therefore a type variable. Normally this variable would be defined as a type parameter on the MyType type being defined, like data MyType v = Null | Container TypeA v. You cannot normally use free variables, so this was another error in your original example.2
Your data declaration showed how the distinction between constructors and variables matters at the type level. This distinction between variables and constructors is also present at the value level. It's how the compiler can tell (when you're writing pattern matches) which terms are patterns it should be checking the data against, and which terms are variables that should be bound to whatever the data contains. For example:
lookAtMaybe :: Show a => Maybe a -> String
lookAtMaybe Nothing = "Nothing to see here"
lookAtMaybe (Just x) = "I found: " ++ show x
If Haskell didn't have the first-letter rule, then there would be two possible interpretations of the first clause of the function:
Nothing could be a reference to the externally-defined Nothing constructor, saying I want this function rule to apply when the argument matches that constructor. This is the interpretation the first-letter rule mandates.
Nothing could be a definition of an (unused) variable, representing the function's argument. This would be the equivalent of lookAtMaybe x = "Nothing to see here"
Both of those interpretations are valid Haskell code producing different behaviour (try changing the capital N to a lower case n and see what the function does). So Haskell needs a rule to choose between them. The designers chose the first-letter rule as a way of simply disambiguating constructors from variables (that is simple to both the compiler and to human readers) without requiring any additional syntactic noise.
1 The rule about the case of the first letter applies to alphanumeric names, which can only consist of letters, numbers, and underscores. Haskell also has symbolic names, which consists only of symbol characters like +, *, :, etc. For these, the rule is that names beginning with the : character are constructors, while names beginning with another character are variables. This is how the list constructor : is distinguished from a function name like +.
2 With the ExistentialQuantification extension turned on it is possible to write data MyType = Null | forall v. Container TypeA v, so that the the constructor has a field with a variable type and the variable does not appear as a parameter to the overall type. I'm not going to explain how this works here; it's generally considered an advanced feature, and isn't part of standard Haskell code (which is why it requires an extension)

Make a type be either one type or another

I'm a beginner in Haskell playing around with parsing and building an AST. I wonder how one would go about defining types like the following:
A Value can either be an Identifier or a Literal. Right now, I simply have a type Value with two constructors (taking the name of the identifier and the value of the string literal respectively):
data Value = Id String
| Lit String
However, then I wanted to create a type representing an assignment in an AST, so I need something like
data Assignment = Asgn Value Value
But clearly, I always want the first part of an Assignment to always be an Identifier! So I guess I should make Identifier and Literal separate types to better distinguish things:
data Identifier = Id String
data Literal = Lit String
But how do I define Value now? I thaught of something like this:
-- this doesn't actually work...
data Value = (Id String) -- How to make Value be either an Identifier
| (Lit String) -- or a Literal?
I know I can simply do
data Value = ValueId Identifier
| ValueLit Literal
but this struck me as sort of unelegant and got me wondering if there was a better solution?
I first tried to restructure my types so that I would be able to do it with GADTs, but in the end the simpler solution was to go leftroundabout's suggestion. I guess it's not that "unelegant" anyways.

ADT - constructor and type -- function accepting only one of the constructors

I wrote the hsexif library and I would now add a feature, but I'm not sure how to prepare the API.
I have the ExifValue type. A ExifValue can be among others a ExifRational, which has a numerator and a denominator. Often you want to display that value (show) as "num/den", for instance for an exposition time of 1/160.
However sometimes you want to show it as a floating-point number, for instance for the exposure compensation, which you would display as "-0.75" for instance, or the aperture ("6.3").
So I want to add a function:
formatAsFloatingPoint :: ExifValue -> Int -> String
The function takes the exif value and the number of floating points after the comma to output in the result string, and returns the formatted string.
However the function will then accept any ExifValue and the user will get a runtime error and no compile time warning if it gives a ExifText as a parameter to that function...
How would I go to make a clean and type-safe API in this case?
You need to think about how you expect this to be used.
The caller might always know they have an ExifRational and will only call formatAsFloatingPoint with such a value. In that case it would make sense to refactor your datatype:
data Rational = Rational !Int !Int
data ExifValue = ... | ExifRational Rational | ...
(or perhaps reuse some existing type for expressing rationals)
and then make formatAsFloatingPoint take a Rational:
formatAsFloatingPoint :: Rational -> Int -> String
This moves the responsibility to the caller to decide when to call it.
Alternatively, perhaps callers just want to display an arbitrary ExifValue, but with special behaviour if the value happens to be an ExifRational. In that case, just use a catch-all case, e.g.:
formatAsFloatingPoint :: ExifValue -> Int -> String
formatAsFloatingPoint n (ExifRational num den) = ...
formatAsFloatingPoint _ v = show v
There are more complicated approaches based on using a type parameter to flag what kind of thing you have, but that would involve refactoring the entire library and there's little evidence that's warranted here. If you have a more general problem across the codebase of wanting to signal that you have specific kinds of ExifValue, they might make sense.

Haskell, parameterized datatype converting to String

Here is my datatype:
data Foo a = Value Integer
|Boo a
and I have a function for converting the Foo datatype to String:
showFoo::Show a=> Foo a -> String
showFoo (Value n) = show n
showFoo (Boo a) = show a
For example: showFoo (Value 10) becomes: "10", but for showFoo(Boo "S"), it becomes: "\"S\"" but I need only "S".
This boils down to the behaviour of show with strings.
show is designed to give machine-readable output, it's not a pretty-printer,
so it puts inverted commas round all strings. That way it can tell the
difference between 10 and "10" when it's reading them back in.
Your showFoo function is clearly not designed to be in the show family,
since it obliterates the Value and Boo tags, so using show isn't really what
you mean.
Possible solutions:
Give in, go the whole hog and derive Show.
If a is always a String, change your data type and don't use show.
Learn about type classes some more and define your own Showish class.
Use -XFlexibleInstances and -XOverlappingInstances to override
the instance for String, and don't use quotes.
Hack it by using init.tail.show $ a
That's just a result of you using GHCi and it showing the previous result. Try this in a compiled program or try running (in GHCi) putStrLn (showFoo (Boo "S")) and you will see that calling show on a string results in a single set of quotes.

Can I have a value constructor named "/""?

I've declared a recursive data type with the following structure:
data Path = GET | POST | Slash Path String
I'd really like to rename that last value constructor to / so that I can infix it in cute expressions like GET /"controller"/"action". However, if I try to do so:
import Prelude hiding ((/))
infixr 5 /
data Path = GET | POST | Path / String
...then I get this:
Path.hs:4:30: parse error on input `/'
Those same three lines compile just fine if I replace / with :/ or any other special character sequence beginning with :.
So, is there any way I can name my value constructor /? I know that I can just name it Slash and then declare a separate function:
(/) :: Path -> String -> Path
(/) = Slash
...but that won't let me pattern match, as in:
request :: Path -> String
request path = case path of GET /"hello" -> "Hello!"
GET /"goodbye" -> "Goodbye!"
Short answer: No.
Long answer: Type classes, type names, and data constructors must begin with either a capital letter or a colon (some of this requires using a language extension). Everything else must begin with a lowercase letter or any other allowed symbol.
Note that type variables, which are normally lowercase identifiers, follow the same rules and do not begin with a colon.
See also the GHC user's guide for enabling type operators. Data constructors are always allowed, I think.
Personally, in your case I'd just use (:/). It doesn't look that bad, and after a while you get used to ignoring the colons. Some people like a trailing colon as well, especially if the data is "symmetric" in some sense.
No, you can't do this. In pure Haskell 98, user-defined type names and constructors must be alphanumeric and begin with an uppercase letter; this is in section 4.1.2 of the Haskell 98 Report. In GHC, just as user-defined constructors with alphanumeric names must begin with an uppercase letter, user-defined constructors which are operators must begin with a :.1 (The same is true for user-defined type names.) This is documented in section 7.4.2 of the GHC manual. I'd probably use :/, myself, with or without / as a synonym.
1: The reason for the "user-defined" qualification is that there are a few built-in exceptions: ->, [], (), and the tuple types (,), (,,), etc. as type names; and () and the tuple type constructors (,), (,,), etc., as type constructors
I think all constructor operators need to start with a colon, (but I may be wrong).
So you could do:
data Path = GET | POST | Path :/ String

Resources